【问题标题】:Inserting into table with an Identity column while replication causes error in SQL Server复制时插入带有标识列的表会导致 SQL Server 中的错误
【发布时间】:2016-03-17 04:19:15
【问题描述】:

我的数据库中有一个表A_tbl。我在A_tbl 上创建了一个触发器来捕获插入的记录。触发器正在我的队列表B_tbl 中插入记录。此表有一个 Identity 列,其属性“不用于复制”为 1。

  • A_tbl(ID、名称、值)以Id为主键
  • B_tbl (uniqueId, Id) 与 uniqueId 作为 Identity

执行此操作的触发代码:

Insert into B_tbl (Id)
    select i.Id from inserted

现在我的表“B”被复制到另一个数据库服务器,现在当我插入表“A”时,它导致了这个错误:

当 IDENTITY_INSERT 设置为 ON 或复制用户插入 NOT FOR REPLICATION 标识列时,必须为表“B_tbl”中的标识列指定显式值。 (来源:MSSQLServer,错误号:545)

请帮我解决这个问题。

【问题讨论】:

  • 您确定要在插入语句中指定列列表吗?我认为您需要为特定表设置身份插入并通过触发器插入唯一ID值
  • 求您分享表结构、触发代码

标签: sql sql-server database ssms database-replication


【解决方案1】:

你必须这样做

SET IDENTITY_INSERT A_tbl  ON

Insert into B_tbl (uniqueid, Id)
select 1, i.id from inserted

SET IDENTITY_INSERT A_tbl  OFF

【讨论】:

  • in trigger "inserted" 会同时有多条记录,所以如何在插入表时生成uniqueid。
  • 你需要应用一些这样的逻辑:从插入的表中获取 max(uniqueid) 到一个变量中。然后选择 @variable + 1 ,id from inserted
【解决方案2】:

基本上有两种不同的方式来插入记录而不会出错:

1) 当 IDENTITY_INSERT 设置为 OFF 时。主键“ID”不得存在

2) 当 IDENTITY_INSERT 设置为 ON 时。主键“ID”必须存在

根据以下示例,使用 IDENTITY PRIMARY KEY 创建的同一表:

CREATE TABLE [dbo].[Persons] (    
    ID INT IDENTITY(1,1) PRIMARY KEY,
    LastName VARCHAR(40) NOT NULL,
    FirstName VARCHAR(40)
);

1) 在第一个示例中,当 IDENTITY_INSERT 为 OFF 时,您可以向表中插入新记录而不会出错。 “INSERT INTO”语句中的主键“ID”不得存在,并且将自动添加唯一的 ID 值:。如果在这种情况下,INSERT 中存在 ID,您将收到错误“无法为表中的标识列插入显式值...”

SET IDENTITY_INSERT [dbo].[Persons] OFF;
INSERT INTO [dbo].[Persons] (FirstName,LastName)
VALUES ('JANE','DOE'); 
INSERT INTO Persons (FirstName,LastName) 
VALUES ('JOE','BROWN');

TABLE [dbo].[Persons] 的输出将是:

ID    LastName   FirstName
1     DOE        Jane
2     BROWN      JOE

2) 在第二个示例中,您可以在 IDENTITY_INSERT 为 ON 时将新记录插入表中而不会出错。 “INSERT INTO”语句中的主键 “ID”必须存在只要 ID 值不存在:如果 ID 不存在于 INSERT在这种情况下,您将收到错误“必须为标识列表指定显式值...”

SET IDENTITY_INSERT [dbo].[Persons] ON;
INSERT INTO [dbo].[Persons] (ID,FirstName,LastName)
VALUES (5,'JOHN','WHITE'); 
INSERT INTO [dbo].[Persons] (ID,FirstName,LastName)
VALUES (3,'JACK','BLACK'); 

TABLE [dbo].[Persons] 的输出将是:

ID    LastName   FirstName
1     DOE        Jane
2     BROWN      JOE
3     BLACK      JACK
5     WHITE      JOHN

【讨论】:

    【解决方案3】:

    触发代码应包含如下的 Identity insert ON 选项

    SET IDENTITY_INSERT B_tbl ON
    
    Insert into B_tbl (uniqueid,Id)
    select identityvalue,i.Id from inserted
    
    SET IDENTITY_INSERT B_tbl OFF
    

    【讨论】:

    • 这会报错。因为,当 identity_insert 为 ON 时,我们应该在插入列表中明确指定标识列名称
    【解决方案4】:

    只是为喜欢我的人添加一个可能的问题,他们按照书本做了所有事情并且仍然得到消息。

    检查插入时的触发器。他们可能会在执行没有明确标识列值的代码时尝试创建更多行。

    如果是这种情况,请禁用触发器(或删除并重新创建它)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-26
      • 1970-01-01
      • 2021-08-03
      • 1970-01-01
      • 2017-05-30
      相关资源
      最近更新 更多