IDENTITY列が1つしかないテーブルに行を挿入する


83

主キーであるadminIdという1つの列しかないテーブルAdministratorがあります。ビジネスルールのため、このようにする必要があります。

このようなテーブルに値を挿入するストアドプロシージャを作成する方法を一度だけ理解したいと思います。SQL ServerとT-SQLを使用していて、SCOPE_IDENTITY()を使用しようとしましたが、テーブルのINSERT_IDENTITYがfalseまたはoffであるため、機能しません。

新しい行を挿入できるようにするためだけに、ダミー値を挿入したくないのです。ありがとう!


1
明確にするために:あなたの質問は「単一のIDENTITY列を持つSQLServerテーブルに行を挿入する方法」ですか?
gbn 2010年

はい、その通りです。明確にしていただきありがとうございます
Phil

2
ここでの着陸の人にとって、これは前に頼まれていて、正しい答えはここにある:stackoverflow.com/questions/850327/...
BJury

回答:


140

IDENTITYである列が1つある場合は、これを実行してください

INSERT MyTable DEFAULT VALUES;  --allows no column list. The default will be the IDENTITY
SELECT SCOPE_IDENTITY();

あなたがアイデンティティを持っていないなら、あなたはそれを設定できますか?これが最善の方法です。上記のSQLを使用してください。

そうでない場合は、新しい行を挿入します

INSERT MyTable (admidid)
OUTPUT INSERTED.admidid --returns result to caller
SELECT ISNULL(MAX(admidid), 0) + 1 FROM MyTable

ノート:

  • 高負荷では、MAXソリューションが重複して失敗する可能性があります
  • SCOPE_IDENTITYは事後であり、前ではありません
  • SCOPE_IDENTITYは、IDENTITY列でのみ機能します。IDENT_CURRENTを使用した任意のイディオシーも同様です
  • 出力句は、MAXソリューションのSCOPE_IDENTITYを置き換えます

1

IDENTITY_INSERTをselectステートメントに追加する必要があります。

SET IDENTITY_INSERT MyTable ON

INSERT INTO MyTable
(AdminCol)

SELECT AdminColValue

 FROM Tableb

終わったら、忘れずに

SET IDENTITY_INSERT MyTable OFF

これがBOLからどのように機能するかについての良い説明です:http://msdn.microsoft.com/en-us/library/aa259221(SQL.80).aspx


次のようにする必要があります:SET IDENTITY_INSERT Administrator ON INSERT INTO Administrator(SCOPE_IDENTITY())SET IDENTITY_INSERT Administrator OFF?
Phil

はい。それはあなたがする必要があるすべてです。SET ON、コードを記述し、最後にSETOFFします。
DataWriter 2010年

これは正しい答えではないと思います。ID列の場合は、値を追加しないでください。受け入れられた答えは正解です。
うーん2015

0

@Phil:テーブルに自動インクリメントPK列とAdminName列の2つの列があるということではありませんか?AdminNameが入る列が1つしかない場合、AdminNameはPKであり、もちろん文字列を自動インクリメントすることはできません。ビジネスルールでは、完全修飾Windowsユーザー名を主キーにすることを期待していますか?AdminName列に代替の一意のインデックスが必要ないため、これは実行可能で理にかなっています。

ただし、テーブルに1つではなく2つの列がある場合:

SQLServerでは、自動インクリメントはテーブル/列定義の一部です。列を整数として定義してから、増分(通常は1)を指定してID列にしますが、2、5、10などの場合もあります。行を挿入するには、他の列の値を挿入するだけで、PK列には何もしません。

insert into T
(foo)   -- column(s) list
values('bar') -- values list

挿入を行うストアドプロシージャは、SCOPE_IDENTITYをRETURN値にするか、SCOPE_IDENTITYをOUTパラメータとしてクライアントに返すことができます。

PS SCOPE_IDENTITY()は、現在のスコープで最後に生成された自動インクリメントされたID値を返します。次のID値は生成されません。

編集:

おそらく、Administratorsテーブルには一連の管理者が含まれています。ただし、整数の主キー列以外に列がない場合、管理者を識別する方法はありません。あなたができる唯一のことはそれらを互いに区別することです。それはあなたをまったく遠ざけません。ただし、Administratorテーブルに次のいずれかの構造がある場合:

ID   INTEGER PRIMARY KEY AUTOINCREMENT
windowsusername   varchar(50)  (unique index)

または

windowsusername varchar(50) primary key

他のテーブルから管理者のテーブルを参照することができ、外部キーは意味があります。そして、それこそが、単一の整数列で構成されるテーブルに欠けているものです-意味。

2つの列がある場合、ストアドプロシージャに次のことを実行させることができます。

insert into Administrators
(windowsusername)
values('mydomain\someusername');
return SCOPE_IDENTITY();

クライアントプログラムは、自動生成され、新しく挿入された行に割り当てられた自動インクリメントされたIDを戻り値として返します。このアプローチは通常の方法であり、「ベストプラクティス」と見なされていると言えます。

PS「挿入するものがない」場合、「値を挿入する」方法がわからないとおっしゃっています。そこには矛盾があります。挿入するものがない場合、なぜ挿入するのですか?たとえば、顧客についてまったく何も知らないのに、なぜ新しいCUSTOMERレコードを作成するのでしょうか。彼らの名前、都市、電話番号、何もありませんか?


2
私のテーブルには、増分int値であるadminIdという1つの列があります
Phil

それは私が今まで見た中で最も奇妙なデザインであり、私は20年以上ビジネスに携わっており、私の日にいくつかの奇妙なものを見てきました。あなたの質問があるので、どのようにテーブルがそのPK列が含まれているとそれだけでPK列、ない他の列...自動インクリメントのID列として定義されている唯一の主キー列が含まテーブルに挿入します
ティム・

では、反対票は何ですか?どこかで事実上の誤り、またはデザインのメリットの欠如についての意見を表明するための誤り?
ティム

1
DB設計の背後にある理由を明確にするためだけに。1つのテーブルにユーザーがいます。ユーザーと管理者の間に関係がある場合。彼らは管理者として扱われます。実際の一意のID以外に、管理テーブルに保持するものはありません。「実際の」データは、ユーザーテーブルとhas-relation(タイムスタンプ、誰が付与したかなど)にあります。
フィル

1
@Phil:つまり、テーブルと外部キーの関係を使用して、単純なブール値/ビット列で何ができるかを表現しています。このようなビット列をテーブルに追加できない場合があり、いくつかの回避策を考え出す必要があります。But an autoincrementing integer whose autoincrementation must be disabled is a poor solution.必要なのは、usersテーブルと1対1の関係にある並列テーブルであり、そのテーブルにビット列を作成します。その列がtrueの場合、ユーザーがhas-adminであることを意味します。掃除。標準。設計。
ティム
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.