在ID为'表'的表中,当IDENTITY_INSERT设置为OFF时,无法插入显式值到标识列。

7

构建表格并在SQLFiddle上查询结果

我想使用查询语句:

INSERT INTO Price (id_price, id_firm, id_city, name) 
        VALUES 
        ('12002', '1429', '73041', 'АРЕНДА (ПРОКАТ) АВТОКРАНА Г/П 25Т'),
        ('12003', '1429', '73041', 'ПЛИТКА КЕРАМИЧЕСКАЯ ГРАНИТ (КЕРАМОГРАНИТ) АССОРТ.'),
        ('12004', '1429', '73041', 'РАБОТЫ ГРУЗОПОДЪЕМНЫЕ АВТОВЫШКА (ПОДЪЕМНИК)'),
        ('12005', '1429', '73041', 'РАБОТЫ ГРУЗОПОДЪЕМНЫЕ АВТОКРАНОМ Г/П 25Т'),
        ('12006', '1429', '73041', 'РАБОТЫ КОМПРЕССОРОМ ВСЕ ВИДЫ'),
        ('12007', '1429', '73041', 'РАБОТЫ ПОГРУЗОЧНО-РАЗГРУЗОЧНЫЕ АВТОКРАНОМ-МАНИПУЛЯТОРОМ ГРУЖУ-ВОЖУ НА БАЗЕ ГАЗ Г/П 4Т'),
        ('12008', '1429', '73041', 'РАБОТЫ СПЕЦТЕХНИКОЙ ВСЕ ВИДЫ'),
        ('12009', '1429', '73041', 'РАБОТЫ СТРОИТЕЛЬНЫЕ ВСЕ ВИДЫ'),
        ('120010', '1429', '73041', 'ФОРСУНКА Д/КАМАЗ ДВИГАТЕЛЬ КАММИНС (CUMMINS) АССОРТ.');

但我遇到了错误:
Cannot insert explicit value for identity column in table 'Price' when IDENTITY_INSERT is set to OFF.:
    INSERT INTO Price (id_price, id_firm, id_city, name) 
    VALUES 
    ('12002', '1429', '73041', 'АРЕНДА (ПРОКАТ) АВТОКРАНА Г/П 25Т'),
    ('12003', '1429', '73041', 'ПЛИТКА КЕРАМИЧЕСКАЯ ГРАНИТ (КЕРАМОГРАНИТ) АССОРТ.'),
    ('12004', '1429', '73041', 'РАБОТЫ ГРУЗОПОДЪЕМНЫЕ АВТОВЫШКА (ПОДЪЕМНИК)'),
    ('12005', '1429', '73041', 'РАБОТЫ ГРУЗОПОДЪЕМНЫЕ АВТОКРАНОМ Г/П 25Т'),
    ('12006', '1429', '73041', 'РАБОТЫ КОМПРЕССОРОМ ВСЕ ВИДЫ'),
    ('12007', '1429', '73041', 'РАБОТЫ ПОГРУЗОЧНО-РАЗГРУЗОЧНЫЕ АВТОКРАНОМ-МАНИПУЛЯТОРОМ ГРУЖУ-ВОЖУ НА БАЗЕ ГАЗ Г/П 4Т'),
    ('12008', '1429', '73041', 'РАБОТЫ СПЕЦТЕХНИКОЙ ВСЕ ВИДЫ'),
    ('12009', '1429', '73041', 'РАБОТЫ СТРОИТЕЛЬНЫЕ ВСЕ ВИДЫ'),
    ('120010', '1429', '73041', 'ФОРСУНКА Д/КАМАЗ ДВИГАТЕЛЬ КАММИНС (CUMMINS) АССОРТ.');

告诉我,为什么会出现错误,如何正确地插入数据?

3
这个问题已经在这里得到了解答:https://dev59.com/iXM_5IYBdhLWcg3wiDyA。 - Brian H
1
错误信息有什么不清楚的地方吗? - user330315
在插入之前将 IDENTITY_INSERT 设置为 ON - user2989408
2
不要向 IDENTITY 列插入显式值!让 SQL Server 处理这些自增值! - marc_s
2个回答

23
SET IDENTITY_INSERT Table_Name ON;
GO

    /* Do your Inserts */

SET IDENTITY_INSERT Table_Name OFF;
GO

注意

这并不是一个好的实践,完全不建议这样做。你很可能最终会得到重复的值,让身份列为你生成值。如果你想自己插入值,则不要将其作为标识列。

如果你正在显式地在一个标识列中插入值,为了确保你永远不会出现重复的值,你可以在显式插入值后重新设置标识列的值:

DBCC CHECKIDENT ('Table_Name', RESEED, 0); --<-- Reseed value to 0
GO

DBCC CHECKIDENT ('Table_Name', RESEED);    --<-- Reseed value to next available value
GO

2
我并不完全同意你的观点。在某些情况下这是很方便的,例如在一个参考数据脚本中设置应用程序的初始数据(例如首次安装时)。想象一下你的应用程序通过前端添加用户(因此需要身份列),但你想先从管理员用户开始,因此你需要编写一个初始脚本来设置它。您可能需要在脚本的后面将此用户的ID作为另一个表中的外键使用,因此需要显式指定。 - Martin Wilson
1
@MartinWilson同意。有时这是唯一的方法,但我已经向OP提供了“最佳实践”的建议,特殊情况下你别无选择。但在这种情况下,当我必须插入值到标识列中时,我会确保使用DBCC RESEED命令将该值重新设置为插入后的下一个最高值,但我想这对于一个简单的答案来说可能过于详细了。 - M.Ali

1
如果这是错误,则您可以执行截断并重新加载表格或者...
SET IDENTITY_INSERT Tablename ON/OFF

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接