插入到 table 时出现问题 - 必须为 table 中的标识列指定显式值

Inserting to table having issue - Explicit value must be specified for identity column in table

我正准备发布一个存储过程,它从其他 table 获取信息,进行预检查,然后将好的数据插入(新)table。我不太习惯使用键和新的 tables,我插入到我正在创建的这个新的 table 中时出现了与 insert/key 有关的错误消息:

Msg 545, Level 16, State 1, Line 131
Explicit value must be specified for identity column in table 'T_1321_PNAnnotationCommitReport' either when IDENTITY_INSERT is set to ON or when a replication user is inserting into a NOT FOR REPLICATION identity column.

BEGIN
...
    BEGIN
    IF NOT EXISTS (SELECT * FROM sys.tables where name = N'T_1321_PNAnnotationCommitReport')
        BEGIN
            CREATE TABLE T_1321_PNAnnotationCommitReport (
                 [id] [INT] IDENTITY(1,1) PRIMARY KEY NOT NULL,  --key
                 [progressnote_id] [INT] NOT NULL,
                 [form_id] [INT] NOT NULL,
                 [question_id] [INT],
                 [question_value] [VARCHAR](max),
                 [associatedconcept_id] [INT],
                 [crte_date] [DATETIME] DEFAULT CURRENT_TIMESTAMP,
                 [create_date] [DATETIME] --SCHED_RPT_DATE
            );
            print 'test';
            
        END
    END --if not exists main table
            SET IDENTITY_INSERT T_1321_PNAnnotationCommitReport ON;
...
    INSERT INTO dbo.T_1321_PNAnnotationCommitReport--(progressnote_id,form_id,question_id,question_value,associatedconcept_id,crte_date, create_date)  **I tried with and without this commented out part and it's the same.
        SELECT  progressnote_id,
                a.form_id,
                question_id,
                questionvalue,
                fq.concept_id,
                getdate(),
                a.create_date
        FROM (
            SELECT  form_id,
                    progressnote_id,
                    R.Q.value('@id', 'varchar(max)') AS questionid,
                    R.Q.value('@value', 'varchar(max)') AS questionvalue,
                    create_date
            FROM
                    @tableNotes t
            OUTER APPLY t.form_questions.nodes('/RESULT/QUESTIONS/QUESTION') AS R(Q)
            WHERE ISNUMERIC(R.Q.value('@id', 'varchar(max)')) <> 0
            ) a
        INNER JOIN [CKOLTP_DEV]..FORM_QUESTION fq ON
                   fq.form_id = a.form_id AND
                   fq.question_id  = a.questionid
                   --select * from T_1321_PNAnnotationCommitReport
                   SET IDENTITY_INSERT T_1321_PNAnnotationCommitReport OFF;
END

有什么想法吗?

我看了一些我们在工作中做的类似插入,insert into select and error message, and insert key auto-incremented,我想我正在做他们做的事情。还有其他人看到我的错误吗?非常感谢。

重复我在问题下的评论:

The error is literally telling you the problem. You turn change the IDENTITY_INSERT property to ON for the table T_1321_PNAnnotationCommitReport and then omit the column id in your INSERT. If you have enabled IDENTITY_INSERT you need to supply a value to that IDENTITY, just like the error says.

我们可以使用以下批次轻松地复制此问题:

CREATE TABLE dbo.MyTable (ID int IDENTITY(1,1),
                          SomeValue varchar(20));
GO

SET IDENTITY_INSERT dbo.MyTable ON;
--fails
INSERT INTO dbo.MyTable (SomeValue)
VALUES('abc');
GO

如果您希望自动生成 IDENTITY 值,请将 IDENTITY_INSERT 设置为 OFF 并省略 INSERT 中的列(如上):

SET IDENTITY_INSERT dbo.MyTable OFF; --Shouldn't be needed normally, but we manually changed it before
--works, as IDENTITY_INSERT IS OFF

INSERT INTO dbo.MyTable (SomeValue)
VALUES('abc');

如果您确实特别想定义 IDENTITY 的值,那么您需要同时将 IDENTITY_INSERT 设置为 ON INSERT 语句中提供一个值:

SET IDENTITY_INSERT dbo.MyTable ON;
--works
INSERT INTO dbo.MyTable (ID,SomeValue)
VALUES(10,'def');
GO

SELECT *
FROM dbo.MyTable;

IDENTITY_INSERT不是说“让RDBMS得到'insert'的值”而是说想告诉RDBMS什么值至 INSERT。这包含在文档 SET IDENTITY_INSERT (Transact-SQL):

的开头句中

Allows explicit values to be inserted into the identity column of a table.

(强调我的)