IDENTITY
アプリケーションのフォームに確実に値を表示する唯一の方法は、 INSERT IT FIRSTです。IDENT_CURRENT
あなたがそれをテストしている唯一の人であれば、あなたを助けるように見えるかもしれませんが、複数のユーザーがあなたのアプリケーションを使用すると、これはすぐに崩壊するでしょう. 証明するのもとても簡単です。次のテーブルを作成します。
CREATE TABLE dbo.whatever(ID INT IDENTITY(1,1), blat CHAR(1));
ここで、2 つの別々の Management Studio ウィンドウで、最初に次のコードを実行します。このコードは、受け入れられた回答に従い、「機能する」と言った場合に、フォームに表示される内容をシミュレートします。
SELECT IDENT_CURRENT('dbo.whatever');
出力に注意してください (両方とも である必要があります1
)。正解です。これまでのところ。
ここで、1 つのウィンドウで次のコマンドを実行します。
INSERT dbo.whatever(blat) SELECT 'x';
SELECT SCOPE_IDENTITY();
出力は次のようになります1
(これも正しいSO FARです)。
次に、別のウィンドウで同じことを実行しますが、に変更x
しy
ます。この出力は現在2
. うーん。これは、フォームでこのユーザーに表示したものと一致しません。1
テーブルにと2
のIDENTITY
値を持つ 2 つの行があることを確認することで、それを検証することもできます。
SELECT ID, blat FROM dbo.whatever;
これを行う正しい方法と唯一の方法は、行を挿入し、値を取得して、フォームに表示することです。事前にサロゲート値を表示する必要がある場合 (なぜこれを行う必要があるのか、またはいつ取得してもエンド ユーザーがこの値を知る必要があるのか わかりません。なぜユーザーは ID が何であるかを気にするのでしょうか?)別のテーブルを作成し、IDENTITY
そこに値を生成します。
CREATE TABLE dbo.dummy_table(ID INT IDENTITY(1,1) PRIMARY KEY);
GO
CREATE TABLE dbo.real_table(ID INT PRIMARY KEY, ...other columns...);
GO
フォームに「次の」ID を表示したい場合は、次のようにします。
INSERT dbo.dummy_table DEFAULT VALUES;
SELECT SCOPE_IDENTITY();
次に、ユーザーが残りの情報を入力すると、から取得した値を使用して、挿入リストに列を挿入しdbo.real_table
て含めることができます。ユーザーが ID を見て [保存] をクリックしなかった場合、これでもギャップが生じることに注意してください。ただし、その ID は実際のテーブルには含まれていないため、意味がありません。それを見たことがあります( 、および他の考えられていない「最初に値をチェックする」手法で起こりうることとは異なります)。ID
dbo.dummy_table
IDENT_CURRENT
MAX+1
実際の目標が本を 3 部別のテーブルに挿入することである場合、解決策は非常に簡単ですが、最初に本を挿入する必要があります。本の名前と部数を表すパラメータがあると仮定しましょう (他のパラメータも同様です):
DECLARE @Copies INT, @name NVARCHAR(32);
SELECT @Copies = 3, @name = N'Moby Dick';
これで、テーブルに挿入しdbo.Books
、出力を使用して複数の行を他のテーブルに挿入できます ( dbo.Accession
?)。firstの「次の」値をやみくもに推測する必要はありませんBookID
。
DECLARE @BookID INT;
INSERT dbo.Books(name, copies, whatever...) SELECT N'Moby Dick', 3, ...;
SELECT @BookID = SCOPE_IDENTITY();
INSERT dbo.Accession(AccessionID, BookID)
SELECT rn, @BookID
FROM
(
SELECT TOP (@Copies) rn = ROW_NUMBER() OVER (ORDER BY [object_id])
FROM sys.columns ORDER BY [object_id]
) AS y;
これは、カタログ ビューから複数の行を生成するトリックを使用しますが、組み込みのNumbers
テーブルがある場合は、それを使用して効率を向上させる (および権限の制限を緩和する) こともできます。