複数のユーザーが一時テーブルでストアドプロシージャを同時に実行できないのはいつですか?


9

最近TechNetで読んだ一時テーブルに関するドキュメントについて質問があります。そのページの一時テーブルセクションの4番目の段落は、次のようになります。

名前付き制約を使用して一時テーブルが作成され、一時テーブルがユーザー定義のトランザクションのスコープ内で作成される場合、一時テーブルを作成するステートメントを実行できるのは一度に1人のユーザーだけです。たとえば、ストアドプロシージャが名前付きの主キー制約を持つ一時テーブルを作成する場合、そのストアドプロシージャを複数のユーザーが同時に実行することはできません。

私は、インデックス化された一時テーブルを使用する少数のストアドプロシージャを大幅に利用する環境で作業しており、ユーザーが次の処理が始まる前に実行が完了するのを待たなければならないという問題に遭遇したことはありません。それが今後も続くことを願っていますが、この警告が適切に理解されていないと問題になる可能性があることを懸念しています。

具体的には、次の点については不明です。

  1. これはグローバル一時テーブルにのみ適用されますか、それともローカル一時テーブルにも適用されますか?(後者の場合のように)セッションの外部に表示されないテーブルが別のセッションの同時実行を妨げるのは奇妙に思われます。
  2. 「名前付き制約」とは何ですか?すべての制約に名前が付いているわけではありませんか(システムで生成された場合でも)。これは、ユーザー定義のエイリアスを持つ制約を参照していますか?これは私には言い回しのように思えます。
  3. 「複数のユーザー」は実際には複数のセッションを意味しますか?これらの手順は、単一のサービスアカウントを使用してアプリケーションから呼び出されるため、スクリプトへの呼び出しの99.9%はその単一のアカウントによってDBに対して行われます(そして、管理者がバックエンドでときどき呼び出す可能性があるのではないかと心配しています)。サービスアカウントが複数のセッションで同時にsprocを実行できる場合、この問題は私の目的には当てはまりません。

1
一時テーブルにインデックスが付けられているとのことですが、問題は制約についてです。インデックスは制約ではありません。一方に当てはまることは、他方に当てはまる場合とそうでない場合があります。この場合、制約とは異なり、データベース内でインデックス名を複製できます。1つのテーブルでインデックス名を重複させることはできません。そのため、名前付きインデックスは、名前付き制約が引き起こす問題を引き起こしません。
シャノン退職

@Shannon、確かに、私が質問を書いたとき、私はこの点を混乱させていました。サンプルコードとドキュメントで見たプライマリキークラスターとプライマリキーの多用は、クラスター化インデックスが制約であると私に信じさせたと思います。そして、拡張により、すべてのインデックスが制約であると推測します。私は前に軽い午後の読書をしましたが、これは私のためにこれを片付けました。
ウェズリーマーシャル

回答:


10

で名前を重複させることはできないので、私はそれを考えていますtempdb.sys.key_constraints。ここに、私のサーバーの1つにあるメタデータビューの内容を示します。

初見

で終わる奇妙な名前はすべて、_6E...SQL Serverによって自動的に生成された名前でした。作成時に明示的に名前を付けなかったため、名前付き制約ではありません。SQL Serverは、理論的には名前の衝突を回避する舞台裏で制約名を生成します。

2つの異なるセッションで次のテーブルを作成しようとすると、

create table #x1 (
ID INT NOT NULL,
CONSTRAINT NAMED_CONSTRAINT_1 PRIMARY KEY (ID)
);

2番目に実行されるものはエラーをスローします。

メッセージ2714、レベル16、状態5、行1

データベースにはすでに「NAMED_CONSTRAINT_1」という名前のオブジェクトがあります。

メッセージ1750、レベル16、状態1、行1

制約またはインデックスを作成できませんでした。以前のエラーを参照してください。

ビューをもう一度チェックアウトします。

制約あり

2つのセッションで次のテーブルを作成しようとしても問題はありません。

create table #y1 (
ID INT NOT NULL,
PRIMARY KEY (ID)
);

メタデータビューは次のとおりです。

デフォルトの制約あり

質問に直接答えるだけです。引用した部分はローカルとグローバルの両方の一時テーブルに適用され、名前付き制約は意図的に名前を付けたものであり、複数のユーザーは複数のセッションを意味します。


11

これはローカル一時テーブルに適用されます。

名前付き制約と名前なし制約の違いは次のとおりです。

CREATE TABLE #t1 (c1 INT PRIMARY KEY CLUSTERED)

CREATE TABLE #t2 (c1 INT,
                     CONSTRAINT pk_c1 PRIMARY KEY  CLUSTERED(c1) )

システム名の制約を許可すると、衝突が発生する可能性が非常に低くなります。この例では、SSMSで2つのウィンドウを開いた場合#t1、両方で作成できますが、では作成できません#t2

グローバル一時テーブルはすべてのユーザーによって共有されるため、異なる方法で処理する必要があります。それらは、最後のセッションがそれらを使用して完了するまで「破壊」されないため、ユーザーがそれらにアクセスするとき、ユーザーが自分のデータにのみアクセスできることを確認する必要があります。これは、SPIDによって行われることもあれば、ハッシュ値によって行われることもあります。グローバル一時テーブルの使用方法によって異なります。

通常、グローバルな一時テーブルのために、ストアドプロシージャは、彼らが存在するかどうかを確認し、場合にのみ、それらを作成しますOBJECT_ID()ですNULL

複数のユーザーとは、複数のセッションを意味します。ログイン名はそれとは無関係です。Georgeが実行されsp_something @i = 1、Ginaが実行sp_something @i = 2される場合、両方がとしてログインしているかどうかは関係ありませんUser1。これらのSPIDは異なります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.