【问题标题】:How to turn IDENTITY_INSERT on and off using SQL Server 2008?如何使用 SQL Server 2008 打开和关闭 IDENTITY_INSERT?
【发布时间】:2011-10-27 04:04:23
【问题描述】:

IDENTITY_INSERT 设置为OFF 时,为什么我在插入时会出错?

如何在 SQL Server 2008 中正确打开它?是使用 SQL Server Management Studio 吗?

我已经运行了这个查询:

SET IDENTITY_INSERT Database. dbo. Baskets ON

然后我在控制台中收到命令成功完成的消息。 但是,当我运行该应用程序时,它仍然给我如下所示的错误:

Cannot insert explicit value for identity column in table 'Baskets' when 
IDENTITY_INSERT is set to OFF.

【问题讨论】:

  • 请扩展此问题,以便我们了解您要执行的操作。遇到此错误时您正在运行什么语句,错误消息的实际文本是什么?
  • 即使您问了另一个问题,您也应该在这里接受答案:我们回答了您的问题
  • 我害怕有人试图从应用程序发送身份值。除了不频繁的数据迁移之外,这不是您应该做的事情。如果您经常这样做以从应用程序中运行它,那么您可能需要重新审视您的表格设计。
  • 我在我的 SQL 脚本备份中使用它。在还原期间,这让我将数据加载到具有原始值的自动增量表中。脚本备份让我可以降级 SQL 数据库。如果我将二进制数据存储在文本字段中,Management Studio 的脚本备份实现会使脚本无法加载。

标签: sql sql-server-2008


【解决方案1】:

另一个选项是你有像'type'或'status'这样的表,例如OrderStatus,你总是想要控制Id值,创建Id(主键)列而不是Identity列是第一名。

【讨论】:

    【解决方案2】:

    根据MSDN通过SQL

    SET IDENTITY_INSERT sometableWithIdentity ON
    
    INSERT INTO sometableWithIdentity 
        (IdentityColumn, col2, col3, ...)
    VALUES 
        (AnIdentityValue, col2value, col3value, ...)
    
    SET IDENTITY_INSERT sometableWithIdentity OFF
    

    完整的错误信息准确地告诉你出了什么问题...

    当 IDENTITY_INSERT 设置为 OFF 时,无法为表“sometableWithIdentity”中的标识列插入显式值。

    【讨论】:

    • @Beginner:你是,因此错误。我们如何知道您不想想要插入值?我们只有一条错误消息
    • 当我执行 DB.SaveChanges() 时,错误来自我的应用程序;
    • 不,只是停止发送标识列的值。或者如果你想在你的应用程序中设置它,如果你想发送一个值.....但是为什么要设置一个带有标识属性的列来生成值?我们无法为您做出决定
    • @Beginner:该设置仅适用于当前会话(没有人明确指出这个问题),因此您的应用程序必须打开它才能让应用程序执行此类插入(最好在此类插入结束时立即将其再次关闭,例如 gbn 节目)。您如何在标识列上插入一个值而没有意识到它并不清楚,但是当 Ismael 似乎暗示未指定显式插入列(?)时,旧版本的 SQL Server 可能会将其隐式包含在所有列中。跨度>
    • @Rob,我认为你有一个观点,我个人未能对任何插入但未指定列的代码进行代码审查。除了在错误上浪费时间之外,这是一种冒险的做法,如果列数据不正确匹配,您最终可能会遇到严重的数据完整性问题。
    【解决方案3】:

    看起来有必要在每个 SQL INSERT 发送批处理之前放置一个SET IDENTITY_INSERT Database.dbo.Baskets ON;

    您可以发送多个以SET IDENTITY_INSERT ... ON; 开头的字符串开头的INSERT ... VALUES ... 命令。只是不要在两者之间放置任何批次分隔符。

    我不知道为什么SET IDENTITY_INSERT ... ON 在发送块之后停止工作(例如:C# 中的.ExecuteNonQuery())。我不得不再次将SET IDENTITY_INSERT ... ON; 放在下一个 SQL 命令字符串的开头。

    【讨论】:

    【解决方案4】:

    我知道这是一个较旧的线程,但我只是碰到了这个。如果用户在其他会话设置 IDENTITY_INSERT ON 之后尝试在 Identity 列上运行插入,那么他一定会收到上述错误。

    设置标识插入值和随后的插入 DML 命令将由同一会话运行。

    这里@Beginner 将 Identity Insert 单独设置为 ON,然后从他的应用程序运行插入。这就是为什么他得到以下错误:

    Cannot insert explicit value for identity column in table 'Baskets' when 
    IDENTITY_INSERT is set to OFF.
    

    【讨论】:

      【解决方案5】:

      导入: 您必须在INSERT 语句中写列

      INSERT INTO TABLE
      SELECT * FROM    
      

      不正确。

      Insert into Table(Field1,...)
      Select (Field1,...) from TABLE
      

      是正确的

      【讨论】:

      • 谢谢,很有帮助
      • 如果您在两个表中都有相同的列,您可以不列出 select(Field1..) 中的列 像这样....插入 Table(Field1,...) Select * from TABLE... 如果您有 Identity 字段要先插入,请执行**SET IDENTITY_INSERT Table_name ON
      • @user3590235 这是一个冒险的假设,列列表是相同的。在手动用户查询之外,永远不要这样做,因为我保证有一天当其他人修改表定义而不更新您的参考时,您会破坏 PROD。
      【解决方案6】:

      您需要在设置身份插入后添加命令“go”。 示例:

      SET IDENTITY_INSERT sometableWithIdentity ON
      go
      
      INSERT sometableWithIdentity (IdentityColumn, col2, col3, ...)
      VALUES (AnIdentityValue, col2value, col3value, ...)
      
      SET IDENTITY_INSERT sometableWithIdentity OFF
      go
      

      【讨论】:

      • 这个问题已经有四年了,并且有一个公认的答案。您的答案与接受的答案重复
      • 嗯,不是完全重复——他确实包含了“go”命令......;)
      【解决方案7】:

      当您有一个 PRIMARY KEY 字段并且您正在插入一个重复的值或者您将 INSERT_IDENTITY 标志设置为 on 时,这很可能发生

      【讨论】:

        【解决方案8】:

        我遇到了一个问题,即使在将 IDENTITY_INSERT 设置为 ON 之后,它也不允许我插入它。

        问题是我没有指定列名,并且由于某种原因它不喜欢它。

        INSERT INTO tbl Values(vals)
        

        所以基本上做完整的 INSERT INTO tbl(cols) Values(vals)

        【讨论】:

        • 这正是我想要的,指定列列表(桌子上的两列,等等)
        猜你喜欢
        • 2011-10-27
        • 1970-01-01
        • 2014-08-19
        • 2012-01-17
        • 1970-01-01
        • 2011-10-20
        • 1970-01-01
        • 1970-01-01
        • 2010-09-23
        相关资源
        最近更新 更多