我将 IDENTITY_INSERT 设置为 ON,但收到 SqlException 提示它已关闭
我试图从文本文件中获取数千张发票(和其他内容)并将它们插入到 SQL Server 2008 中。我编写了一个小控制台应用程序来执行此操作,它使用 LINQ to SQL。插入所有现有发票后,我希望 Invoice_ID
成为标识列并自动递增,因此我将其设计如下:
CREATE TABLE [dbo].[Invoice]
(
[Invoice_ID] int IDENTITY(1,1) NOT NULL PRIMARY KEY,
/* Other fields elided */
)
在开始插入发票之前,我调用一个包含以下内容的存储过程行:
SET IDENTITY_INSERT [dbo].[Invoice] ON;
/* Other lines for setup elided */
提交更改后,我使用以下行调用另一个存储过程:
SET IDENTITY_INSERT [dbo].[Invoice] OFF;
/* Other lines for clean up elided */
当我尝试插入发票并提交更改时,出现以下异常:
SQLException:当 IDENTITY_INSERT 设置为 OFF 时,无法在表“Invoice”中插入标识列的显式值。
我运行了 SQL Profiler,可以看到它确实在尝试执行插入之前将 IDENTITY_INSERT
设置为 ON
。我没有看到它在任何地方被设置为 OFF
。我对 SQL Profiler 还很陌生,所以也许我可以启用一个事件,该事件将为我提供更多信息来尝试和调试它。有什么想法吗?
我尝试调整 LINQ to SQL 使用的 .dbml 文件中的值。我将发票
表的自动生成值
设置为“False”,将自动同步
设置为“从不”,并将服务器数据类型
设置为“Int NOT NULL”。通常我会将它们分别设置为“True”、“On Insert”和“Int NOT NULL IDENTITY”,但是当我这样做时,我可以看到 SQL Server 正在执行:
选择 CONVERT(Int,SCOPE_IDENTITY()) AS [值]
而不是插入我提供的 Invoice_ID
。
I'm trying to grab thousands of invoices (and other stuff) from a text file and insert them into SQL Server 2008. I wrote a little console app to do this and it uses LINQ to SQL. After I insert all the existing invoices I want the Invoice_ID
to be an identity column and auto-increment, so I have it designed as such:
CREATE TABLE [dbo].[Invoice]
(
[Invoice_ID] int IDENTITY(1,1) NOT NULL PRIMARY KEY,
/* Other fields elided */
)
Before I start inserting invoices I call a stored procedure that contains the following line:
SET IDENTITY_INSERT [dbo].[Invoice] ON;
/* Other lines for setup elided */
After I've submitted my changes I call another stored procedure with the following line:
SET IDENTITY_INSERT [dbo].[Invoice] OFF;
/* Other lines for clean up elided */
When I try inserting my invoices and submitting the changes I get the following exception:
SQLException: Cannot insert explicit value for identity column in table 'Invoice' when IDENTITY_INSERT is set to OFF.
I ran SQL Profiler and I can see that it is indeed setting IDENTITY_INSERT
to ON
before trying to perform the inserts. I do not see it being set to OFF
anywhere. I'm pretty new to the SQL Profiler, so maybe there's an event I can enable that will provide me with more info to try and debug this. Any ideas?
I've tried tweaking values in the .dbml file that's used by LINQ to SQL. I have the Invoice
table's Auto Generated Value
set to "False", Auto-Sync
set to "Never", and the Server Data Type
set to "Int NOT NULL". Normally I'd have them set to "True", "On Insert", and "Int NOT NULL IDENTITY", respectively, but when I do I can see that SQL Server is excecuting:
SELECT CONVERT(Int,SCOPE_IDENTITY()) AS [value]
rather than inserting the Invoice_ID
that I provide.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
http://msdn.microsoft.com/en-us/library/ms190356。 aspx
如果你往下看,你可以看到:
http://msdn.microsoft.com/en-us/library/ms190356.aspx
If you look down, you can see:
虽然 IDENTITY_INSERT 的范围似乎是一个问题,但我在 EF v4.1 中找到并测试的解决方案是首先打开连接,以便会话保持打开状态。例如,
我测试了这个解决方案,没有调用 context.Connection.Open();首先,它按照描述失败了。然后我添加了它完美运行的行。
While the scope of the IDENTITY_INSERT seems to be a problem, the solution I've found and tested in EF v4.1 is to open the connection first so that the session remains open. E.g.
I tested this solution without calling context.Connection.Open(); first, and it failed as described. Then I added the line it worked perfectly.
我希望 SET IDENTITY_INSERT 的范围仅限于过程的主体。我见过的最常见的方法是创建一个存储过程,它使用 EXEC 来执行包含 SET IDENTITY_INSERT 和 INSERT 本身的动态 SQL。
I would expect SET IDENTITY_INSERT is scoped to the body of the procedure. The most common approach I've seen is to make a stored procedure which uses EXEC to execute dynamic SQL containing both the SET IDENTITY_INSERT and the INSERT itself.