SQL Server生成的bug数据脚本如何不在insert语句中设置IDENTITY?

时间:2016-12-25 09:38:20

标签: sql-server ssms

我正在使用SQL Server Management Studio生成一个SQL脚本(大脚本)来更新Azure SQL数据库。问题是脚本是在IDENTITY打开的情况下生成的,插入语句是使用ID列导出的,结果导致此错误:

  

无法在表'Table_Name'中为identity列插入显式值   当IDENTITY_INSERT设置为OFF时。

我的问题是如何生成不会使用IDENTITY和插入的脚本?

2 个答案:

答案 0 :(得分:1)

在此使用set identity_insert的快速示例:http://rextester.com/NGN7719

在Sql Server Management Studio(SSMS)中使用生成脚本任务生成包含数据的脚本时,将为包含标识列的表包含set identity_insert语句。

在对象资源管理器中:任务 - >生成脚本 - > [所有表格选定的表格] - >高级 - > [具有数据数据的模式]

  • 如果来自的脚本数据表没有带有identity属性的列,则它不会生成set identity_insert语句。

  • 如果来自的脚本数据表的列具有标识属性,则会生成set identity_insert语句。

经测试&确认使用SSMS 208& SSMS 2012

在OP的情况下,我猜测源表没有在源表中为my_table_id设置标识属性,但是在目标表中为my_table_id设置了标识属性。

要获取所需的输出,请将表更改为脚本数据,以使my_table_id具有标识属性。

本文深入介绍了执行此操作的步骤(不使用SSMS中的设计器):Add or drop identity property for an existing SQL Server column - Greg Robidoux

  • 使用标识属性

  • 创建一个新列
  • 将数据从现有id列传输到新列

  • 删除现有的id列。

  • 将新列重命名为原始列名

 

这是上面rextester示例中使用的示例代码。

create table table_w_identity (
    IdentityColumn int identity (1,1)
  , OtherColumn nvarchar(128)
  , constraint pk_table_w_identity primary key clustered (IdentityColumn asc)
  , constraint uc_table_w_identity_OtherColumn unique (OtherColumn)
  );

set identity_insert dbo.table_w_identity on;
  insert into dbo.table_w_identity (IdentityColumn, OtherColumn)
    values (1, 'identity_insert is on');
    /* succeeds */

set identity_insert dbo.table_w_identity off;
  insert into dbo.table_w_identity (OtherColumn)
    values ('identity_insert is off');
    /* succeeds */

以下两个陈述失败:

set identity_insert dbo.table_w_identity off;
  insert into dbo.table_w_identity (IdentityColumn, OtherColumn)
    values (3, 'identity_insert is off, this fails because identitycolumn is trying to be inserted');
    /* fails */
  

错误:当IDENTITY_INSERT设置为OFF时,无法在表'table_w_identity'中为identity列插入显式值。

set identity_insert dbo.table_w_identity on;
  insert into dbo.table_w_identity (OtherColumn)
    values ('identity_insert is on, this fails b/c identitycolumn is not being inserted');
    /* fails */
  

错误:当IDENTITY_INSERT设置为ON或复制用户插入NOT FOR REPLICATION标识列时,必须为表'table_w_identity'中的标识列指定显式值。

这是我从SSMS生成脚本的输出,仅用于上述rextester中使用的示例表的数据:

SET IDENTITY_INSERT [dbo].[table_w_identity] ON 

INSERT [dbo].[table_w_identity] ([IdentityColumn], [OtherColumn]) VALUES (2, N'identity_insert is off')
INSERT [dbo].[table_w_identity] ([IdentityColumn], [OtherColumn]) VALUES (1, N'identity_insert is on')
SET IDENTITY_INSERT [dbo].[table_w_identity] OFF

文档: - set identity_insert - msdn

答案 1 :(得分:1)

这是一篇很老的文章,但是IMO唯一提供的答案不能解决该问题,即使用“生成脚本”导出/导入数据库充其量是不可靠的。

我有几次使用向导生成脚本,然后在空白数据库中使用它们,并且确实有此错误,而实际上根本没有任何错误的理由。

最好的过程是:

  1. 仅生成模式并首先创建数据库
  2. 禁用所有约束:EXEC sp_MSforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all'
  3. 生成数据,但是,这是关键,不要尝试一次完成所有操作。一次做一张桌子,或成批较小的桌子。
  4. 对于任何错误,请截断该错误批处理中的所有表,并尝试修复该错误。
  5. 如果每个表都成功导入,请重新启用约束:exec sp_MSforeachtable @command1='ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all'

我不知道为什么,但是SSMS和sqlcmd(我在2008 r2上)似乎都在运行大型脚本时遇到问题。我的最后一次失败是连续no value provided for required parameter行,这绝对没问题。当以较小的批次运行时,它可以正常工作。

OP的错误是由于以下事实而导致的:如果发生上述虚假错误,则脚本最终会处于错误状态,并且内置set identity_insert on语句将无法正常工作。

“生成脚本”命令具有“每个对象一个文件”的选项,这也是一种不错的选择。

希望这对某人有帮助!