2012-05-17 35 views
51

Tôi đã tìm kiếm điều này, nhưng chủ đề mà nó xuất hiện có xu hướng có câu trả lời từ những người không hiểu câu hỏi.Làm cách nào để kiểm tra xem IDENTITY_INSERT có được đặt thành BẬT hoặc TẮT trong SQL Server không?

Lấy cú pháp sau:

SET IDENTITY_INSERT Table1 ON 

Làm thế nào để bạn làm điều gì đó như thế này:

GET IDENTITY_INSERT Table1 

Tôi không muốn làm bất cứ điều gì nào để dữ liệu trong cơ sở dữ liệu hoặc đến cài đặt để có được thông tin này mặc dù. Cảm ơn!

+2

Hài hước cách bạn đề cập đến mọi người hiểu nhầm câu hỏi và phần lớn các câu trả lời ở đây làm chính xác điều đó. – Fishcake

+2

Đối với bạn và những người khác googling này, câu hỏi thực sự: * phiên *. Bạn có thể chỉ muốn kiểm tra/khôi phục giá trị của IDENTITY_INSERT cho một phiên * dài và phức tạp, đủ để cho phép và sau đó ngăn chặn chèn thông tin nhận dạng. (Một bước công việc liên tục chạy?) VÌ SAO nếu bạn bắt đầu một phiên mới, 'IDENTITY_INSERT' bị tắt! Nếu bạn không rõ liệu nội dung nào đó có cùng phiên, phiên google (không chính xác = kết nối) hay không, hãy xem 'sys.dm_exec_sessions' và' sys.dm_exec_connections' hoặc tải xuống 'sp_WhoIsActive' và' EXEC sp_WhoIsActive @show_sleeping_spids = 2, @show_own_spid = 1' –

Trả lời

25

SET IDENTITY_INSERT là phiên nhạy cảm, nó được quản lý ở cấp bộ đệm mà không lưu trữ ở đâu đó. Điều này có nghĩa là chúng tôi không cần kiểm tra trạng thái IDENTITY_INSERT vì chúng tôi không bao giờ sử dụng từ khóa này trong phiên hiện tại.

Xin lỗi, không có trợ giúp cho việc này.

Great câu hỏi mặc dù :)

Nguồn: Here

Cập nhật Có nhiều cách có thể để làm điều này, cũng thấy trong các trang web tôi liên kết, IMO, nó là quá nhiều công sức để có ích .

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 
+0

Cảm ơn. Tôi chỉ biết rằng nó tồn tại ngày hôm qua, vì vậy tôi không thực sự chắc chắn làm thế nào để áp dụng những gì bạn đang nói. Về cơ bản chúng tôi có hai cơ sở dữ liệu trên hai máy chủ khác nhau, và tắt một trong hai và khởi động lại nó sẽ là một vấn đề. Phiên bạn đang đề cập kéo dài hơn một vài phút nếu dịch vụ cơ sở dữ liệu còn lại chạy vô thời hạn? Về cơ bản tôi thiết lập giá trị một vài lần trên một trong các cơ sở dữ liệu mà không cần ghi chú trước, và tôi cần phải chắc chắn rằng bất kỳ thay đổi như thế nào được cuộn lại. – Panzercrisis

+1

Lưu ý rằng đây không phải là câu trả lời của riêng tôi, nhưng từ nguồn của tôi tại http://social.msdn.microsoft.com/Forums/en/transactsql/thread/1a6ba2bb-5e82-47e8-a1a0-16fc044b951e (diễn đàn chính thức của Microsoft , có tấn của những đánh dấu.) Tất cả phụ thuộc vào hiệu suất trên các máy chủ này. Rõ ràng, nếu các máy chủ chậm/các dịch vụ liên quan đến SQL Server đang tắt, mã này (trong giả ở đây) sẽ không hoạt động tốt. Tại sao bạn chính xác cần biết trạng thái nhận dạng của các bảng? Nếu dịch vụ chạy vô thời hạn, phiên này không được kéo dài (tùy thuộc vào thông số máy chủ và kích thước bảng) ... – Eon

+0

Tôi chỉ đang cố đặt lại cơ sở dữ liệu về cách trước khi bắt đầu rối loạn với giá trị IDENTITY_INSERT . – Panzercrisis

3

Nếu bạn muốn biết về biến phiên ... Câu hỏi hay, nhưng tôi không thể biết thông tin này hữu ích ở đâu. Trong thực hiện bình thường để kiểm tra một bảng bình thường phản ứng với một chèn, điều này sẽ làm việc!

- Nếu bạn chỉ muốn biết nếu có bản sắc chèn vào một bảng được đưa ra:

select is_identity 
from sys.columns 
where object_id = OBJECT_ID('MyTable', 'U') and name = 'column_Name' 

- Hoặc ... Sử dụng điều này nếu bạn muốn thực hiện một cái gì đó tùy thuộc vào kết quả:

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 

Hãy vui vẻ!

+5

Điều này bỏ lỡ các điểm, câu hỏi là liên quan đến liệu 'IDENTITY_INSERT' là trên không nếu bảng có một cột nhận dạng – Fishcake

+0

' is_identity' cột trong bảng 'sys.columns' xác định xem cột đó là một cột nhận dạng hay không, không cho dù biến 'IDENTITY_INSERT' là' ON' hoặc 'OFF' –

0

bạn cũng có thể sử dụng phương pháp ObjectProperty để xác định xem một bảng có một bản sắc:

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 
1

câu hỏi rất tốt. Tôi có cùng một vấn đề. Có thể bạn có thể thử đặt lại IDENTITY_INSERT bằng TRY/CATCH không? Ví dụ, bạn thực hiện công việc nhưng không chắc chắn nếu công việc được hoàn thành và IDENTITY_INSERT được đặt thành TẮT.

Tại sao bạn không thử:

BEGIN TRY 
... 
END TRY 
BEGIN CATCH 
SET IDENTITY_INSERT table OFF; 
END CATCH; 

Ngoài ra tôi không chắc chắn rằng đây là hoạt động chính xác nhưng tôi thấy rằng việc thêm chỉ SET IDENTITY_INSERT ... OFF không trả về lỗi. Vì vậy, bạn có thể đặt chỉ trong trường hợp vào cuối SET IDENTITY_INSERT ... OFF.

12

Nói tóm lại: giải pháp

  • Nathan là nhanh nhất:

    SELECT OBJECTPROPERTY(OBJECT_ID('MyTable'), 'TableHasIdentity'); 
    
    • khi sử dụng một wrapper API, người ta có thể làm giảm toàn bộ kiểm tra để chỉ kiểm tra cho các hàng. Ví dụ khi sử dụng C# 's SqlDataReaders tài sản HasRows và một truy vấn xây dựng như:

      SELECT CASE OBJECTPROPERTY(OBJECT_ID('MyTable'), 'TableHasIdentity') 
           WHEN 1 THEN '1' ELSE NULL END 
      
  • giải pháp Ricardo cho phép linh hoạt hơn nhưng đòi hỏi tên danh tính của Cột

    giải pháp
    SELECT * FROM sys.columns WHERE object_id = OBJECT_ID('MyTable', 'U') 
             AND name = 'MyTableIdentityColumnName'; 
    
  • Bogdan Bodanov, sử dụng try/catch cũng sẽ hoạt động, nhưng việc kiểm tra bổ sung sẽ hạn chế xử lý ngoại lệ đối với các trường hợp IDENTITY_INSERT is already ON for table 'MyTable'. Cannot perform SET operation for table 'MyTable';

5

Nếu bạn đang cố gắng tắt IDENTITY_INSERT cho một số bảng khác để tránh gặp lỗi khi bạn muốn đặt IDENTITY_INSERT, những điều sau đây cũng có thể phù hợp với bạn. Như những người khác đã nói về chủ đề này, IDENTITY_INSERT là một thiết lập phiên mà không có khả năng hiển thị trực tiếp. Tuy nhiên tôi đã phát hiện thú vị rằng SET IDENTITY_INSERT OFF không lỗi cho bất kỳ bảng nào có một danh tính cho dù IDENTITY_INSERT có BẬT cho bảng đó hay không. Vì vậy, nó xảy ra với tôi rằng tôi chỉ có thể gọi SET IDENTITY_INSERT ... OFF cho mỗi bảng với một bản sắc trong cơ sở dữ liệu. Nó cảm thấy một chút giống như một giải pháp bạo lực, nhưng Tôi thấy rằng khối SQL động sau đây đã làm các trick rất độc đáo.

---- 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 
2

Bạn có thể khám phá xem ident_insert có bật hay không và nếu có thì sử dụng mã nào bên dưới.

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 
+0

mẹo hay với try-catch – Graeme

+1

@Graeme: cảm ơn, tôi nghĩ câu trả lời thực sự cho câu hỏi có thể hữu ích và đó là cách duy nhất tôi biết để làm điều đó. – jmoreno

Các vấn đề liên quan