SQL Server,主键字段无法插入null?

问题描述 投票:0回答:8

当我尝试做这样的陈述时:

INSERT INTO qcRawMatTestCharacteristic 
VALUES (NULL, 1, 1, 1, 1, 1, 1, 1, '', '', '', GETDATE(), 1)

我得到以下信息:

无法将 NULL 值插入 列“iRawMatTestCharacteristicId”, 桌子 'Intranet.dbo.qcRawMatTestCharacteristic'; 列不允许为空。插入 失败了。

我理解该错误,但 null 值适用于具有 int 数据类型的主字段。

有什么想法吗?

sql sql-server database-design insert
8个回答
54
投票

任何关系数据库中的主键都不允许为 NULL - 这是主键的主要基本特征之一。

请参阅:

SQL 设计:如何选择主键

永不为空 主键值不能为空,也不能做任何事情 使主键为空。
这是 不可违反的关系规则 ANSI 支持的模型, 关系数据库管理系统 (RDBMS)设计和 SQL Server。

更新:好的,所以你想要在 SQL Server 中使用“自动增量”主键。

您需要在 CREATE TABLE 语句中将其定义为 INT IDENTITY:

CREATE TABLE dbo.YourTable(ID INT IDENTITY, col1 INT, ..., colN INT)

然后,当您执行 INSERT 时,您需要显式指定要插入的列,但只是不要在该列表中指定“ID”列 - 然后 SQL Server 将自动查找正确的值:

INSERT INTO dbo.YourTable(col1, col2, ..., colN) -- anything **except** `ID` VALUES(va1l, val2, ..., valN)

如果您想在创建表后执行此操作,可以在 SQL Server Management Studio 的表设计器中执行此操作:

alt text


9
投票
MS SQL 中主键字段不能包含空值。 如果您想要填充 SQL 表并且不知道要为基于整数的主键字段输入什么内容,则将 pk 设置为 Identity 字段。 此外,在指定 Insert 语句时,明智的做法是使用 insert 语句的列映射部分,例如:

Insert into (field1, field2, field3) values (value1, value2, value3)

这样做的原因是它确保列顺序是您开发的,因为 SQL 管理员可以修改列顺序。 它还允许您插入具有标识主键的行,而无需指定主键示例

CREATE TABLE [dbo].[foo]( [fooid] [int] IDENTITY(1,1) NOT NULL, [name] [varchar](50) NULL, CONSTRAINT [PK_foo] PRIMARY KEY ( [fooid] ASC )

现在我的插入语句很简单

Insert into foo (name) values ("John")

表中的结果将是

1, "John"
    

4
投票
您可能没有(您忘记添加)在整数主键上设置自动增量。


3
投票
主键不应该接受空值。为什么要向主键字段插入空值?主键字段应该有一个不可为空的唯一值,这将使表中的每条记录都是唯一的


2
投票
您可以仅对 1 个唯一行使用 0 而不是 null,对于 PK 不可能使用 null。或者你可以省略 PK 并使用自动增加 PK 字段


2
投票
假设您的主键有一个自动增量字段,您需要在插入中包含字段列表,而不是为该字段输入值,例如

INSERT INTO qcRawMatTestCharacteristic (Answer1,Answer2,...SomeDateField) VALUES(1,1,1,1,1,1,1,'','','', GETDATE(), 1)
    

2
投票
我假设您真正的问题是您不确定如何编写插入语句以便自动正确填充 PK?您需要命名要为其设置值的字段,看起来您正在尝试设置所有这些字段,但只需排除 PK 字段,如下所示:

INSERT INTO someTable (fieldName1, fieldName2) VALUES(1,1)

其中 sometable 是具有三个字段的表。 PK、字段名称 1 和字段名称 2。您还需要确保 PK 字段上的身份属性设置为 true。


0
投票
如果有标识列,则无需在插入语句中指定它。

INSERT INTO qcRawMatTestCharacteristic VALUES(1,1,1,1,1,1,1,'','','', GETDATE(), 1)

但是,如果您的主键不是标识列,那么您确实需要指定它,因为否则它将尝试插入空值,并且默认情况下主键不可为空。

© www.soinside.com 2019 - 2024. All rights reserved.