私はこれを検索しましたが、それが表示されたスレッドは、質問を理解していない人々からの回答を持っている傾向がありました。
次の構文を使用します。
SET IDENTITY_INSERT Table1 ON
このようなことをどのように行いますか:
GET IDENTITY_INSERT Table1
この情報を取得するために、データベース内のデータや設定に対して何もしたくありません。ありがとう!
SET IDENTITY_INSERT
はセッションに依存するため、どこにも保存せずにバッファレベルで管理されます。つまり、現在のセッションではこのキーWordを使用しないため、IDENTITY_INSERT
ステータスを確認する必要はありません。
申し訳ありませんが、これは役に立ちません。
しかし素晴らしい質問:)
ソース: ここ
Update多分これを行う方法がありますが、リンクしたサイトにも見られます、IMO.
if
(select max(id) from MyTable) < (select max(id) from inserted)
--Then you may be inserting a record normally
BEGIN
set @I = 1 --SQL wants something to happen in the "IF" side of an IF/ELSE
END
ELSE --You definitely have IDENTITY_INSERT on. Done as ELSE instead of the other way around so that if there is no inserted table, it will run anyway
BEGIN
.... Code that shouldn't run with IDENTITY_INSERT on
END
要約すれば:
ネイサンのソリューションは最速です。
SELECT OBJECTPROPERTY(OBJECT_ID('MyTable'), 'TableHasIdentity');
aPIラッパーを使用する場合、チェック全体を行のチェックのみに減らすことができます。たとえば、C#のSqlDataReaders
プロパティHasRows
と次のようなクエリ構造を使用する場合:
SELECT CASE OBJECTPROPERTY(OBJECT_ID('MyTable'), 'TableHasIdentity')
WHEN 1 THEN '1' ELSE NULL END
リカルドのソリューションは柔軟性を高めますが、列の識別名が必要です
SELECT * FROM sys.columns WHERE object_id = OBJECT_ID('MyTable', 'U')
AND name = 'MyTableIdentityColumnName';
try
/catch
を使用するBogdan Bodanovソリューションも同様に機能しますが、追加のチェックは例外処理をIDENTITY_INSERT is already ON for table 'MyTable'. Cannot perform SET operation for table 'MyTable';
の場合に限定する必要があります。
IDENTITY_INSERTをオンに設定するときにエラーが発生しないように、他のテーブルのIDENTITY_INSERTをオフにしようとする場合、次の方法も有効です。このスレッドで他の人が言ったように、IDENTITY_INSERTは直接表示されないセッション設定です。ただし、IDENTITY_INSERTがONであるかどうかに関係なく、IDを持つテーブルに対してSET IDENTITY_INSERT OFFがエラーにならないという興味深い発見をしました。そのため、データベース内のIDを持つすべてのテーブルに対してSET IDENTITY_INSERT ... OFFを呼び出すだけでよいことがわかりました。それはブルートフォースソリューションに少し似ていますが、次の動的SQLブロックが非常にうまく機能していることがわかりました。
---- make sure IDENTITY_INSERT is OFF ----
DECLARE @cmd NVARCHAR(MAX)
SET @cmd = CAST((SELECT 'SET IDENTITY_INSERT ' +
QUOTENAME(OBJECT_SCHEMA_NAME(t.object_id)) + '.' +
QUOTENAME(t.name) + ' OFF' + CHAR(10)
FROM sys.columns c
JOIN sys.tables t ON t.object_id = c.object_id
WHERE c.is_identity = 1
ORDER BY 1 FOR XML PATH('')) AS NVARCHAR(MAX))
EXEC sp_executesql @cmd
Identity_insertがオンになっているかどうか、およびオンになっている場合は、次のコードを使用してどのテーブルを検出することができます。
declare @tableWithIdentity varchar(max) = '';
SET IDENTITY_INSERT ExampleTable ON
begin try
create table #identityCheck (id int identity(1,1))
SET IDENTITY_INSERT #identityCheck ON
drop table #identityCheck
end try
begin catch
declare @msg varchar(max) = error_message()
set @tableWithIdentity= @msg;
set @tableWithIdentity =
SUBSTRING(@tableWithIdentity,charindex('''',@tableWithIdentity,1)+1, 10000)
set @tableWithIdentity = SUBSTRING(@tableWithIdentity,1, charindex('''',@tableWithIdentity,1)-1)
print @msg;
drop table #identityCheck
end catch
if @tableWithIdentity<>''
begin
print ('Name of table with Identity_Insert set to ON: ' + @tableWithIdentity)
end
else
begin
print 'No table currently has Identity Insert Set to ON'
end
セッション変数について知りたい場合...良い質問ですが、この情報がどこで役立つかわかりません。挿入に対する通常のテーブル応答をチェックする通常の実行では、これは機能するはずです!
-特定のテーブルにID挿入があるかどうかだけを知りたい場合:
select is_identity
from sys.columns
where object_id = OBJECT_ID('MyTable', 'U') and name = 'column_Name'
-または...結果に応じて何かを実行する場合は、これを使用します。
if exists (select *
from sys.columns
where object_id = OBJECT_ID('MyTable', 'U') and is_identity = 1)
... your code considering identity insert
else
... code that should not run with identity insert
楽しんで!
とてもいい質問です。同じ問題があります。 TRY/CATCHを使用してIDENTITY_INSERTをリセットできますか?たとえば、ジョブを作成しますが、ジョブが終了し、IDENTITY_INSERTがOFFに設定されているかどうかはわかりません。
試さない理由:
BEGIN TRY
...
END TRY
BEGIN CATCH
SET IDENTITY_INSERT table OFF;
END CATCH;
また、これが正しく機能していることはわかりませんが、SET IDENTITY_INSERT ... OFF
はエラーを返しませんでした。念のため、最後にSET IDENTITY_INSERT ... OFF
。
objectPropertyメソッドを使用して、テーブルにIDがあるかどうかを判断することもできます。
DECLARE @MyTableName nvarchar(200)
SET @MyTableName = 'TestTable'
SELECT CASE OBJECTPROPERTY(OBJECT_ID(@MyTableName), 'TableHasIdentity')
WHEN 1 THEN 'has identity'
ELSE 'no identity columns'
END as HasIdentity