当插入为 NULL 时,“INSERT 语句与 FOREIGN KEY 约束冲突”

Posted

技术标签:

【中文标题】当插入为 NULL 时,“INSERT 语句与 FOREIGN KEY 约束冲突”【英文标题】:"The INSERT statement conflicted with the FOREIGN KEY constraint" when insert is NULL 【发布时间】:2014-11-02 19:14:38 【问题描述】:

我有这个问题:我有这个有 5 列的表:ID, Usuario_IdUsuario, Artista_IdArtista, Disco_IdDisco, Lista_IdLista。最后 4 个是外键,最后 2 个允许空值,因为在创建它们时,它们引用的表是空的。所以我插入 Usuario_IdUsuarioArtsita_IdArtista 并收到以下消息:

INSERT 语句与 FOREIGN KEY 约束“FK_Sigue_Lista”冲突。冲突发生在数据库“Tarea2”、表“dbo.Lista”、列“IdLista”中。 声明已终止。

但是该表是空的,并且没有插入任何内容,因为它允许空值。我已经检查过了,它没有默认值。

注意:这可能被视为“重复”,但之前问题中给出的答案对我不起作用,我无法评论询问如果不起作用会发生什么(默认值)。

出现问题的插入代码:

string insertQuery2 = "insert into Sigue (Usuario_IdUsuario, Artista_IdArtista) values (@usu, @Artista);"; //if I delete the ; inside the "", then it doesn't show any error messages, but it doesn't isert anything into the table either. 
SqlCommand sig = new SqlCommand(insertQuery2, conn);

sig.Parameters.AddWithValue("@usu", idusu); //UserId taken from user table
sig.Parameters.AddWithValue("@Artista", idar); //ArtistId taken from artist table.

sig.ExecuteNonQuery();

我做错了什么?

(我在 Visual Studio 2012 上使用 C#,并在 Management Studio 中使用 SQL Server 2012)

USE [Tarea2] 
GO

/****** Object:  Table [dbo].[Sigue]    Script Date: 02-11-2014 20:32:44 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Sigue](
    [IdSigue] [int] IDENTITY(1,1) NOT NULL,
    [Usuario_IdUsuario] [int] NOT NULL,
    [Artista_IdArtista] [int] NOT NULL,
    [Disco_IdDisco] [int] NULL,
    [Lista_IdLista] [int] NULL,
 CONSTRAINT [PK_Sigue] PRIMARY KEY CLUSTERED 
(
    [IdSigue] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,     ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[Sigue] ADD  CONSTRAINT [DF_Sigue_Disco_IdDisco]  DEFAULT (NULL) FOR     [Disco_IdDisco]
GO

ALTER TABLE [dbo].[Sigue] ADD  CONSTRAINT [DF_Sigue_Lista_IdLista]  DEFAULT (NULL) FOR     [Lista_IdLista]
GO

ALTER TABLE [dbo].[Sigue]  WITH CHECK ADD  CONSTRAINT [FK_Sigue_Artista] FOREIGN     KEY([Artista_IdArtista])
REFERENCES [dbo].[Artista] ([IdArtista])
GO

ALTER TABLE [dbo].[Sigue] CHECK CONSTRAINT [FK_Sigue_Artista]
GO

ALTER TABLE [dbo].[Sigue]  WITH CHECK ADD  CONSTRAINT [FK_Sigue_Disco] FOREIGN     KEY([Disco_IdDisco])
REFERENCES [dbo].[Disco] ([IdDisco])
GO

ALTER TABLE [dbo].[Sigue] CHECK CONSTRAINT [FK_Sigue_Disco]
GO

ALTER TABLE [dbo].[Sigue]  WITH CHECK ADD  CONSTRAINT [FK_Sigue_Lista] FOREIGN     KEY([Lista_IdLista])
REFERENCES [dbo].[Lista] ([IdLista])
GO

ALTER TABLE [dbo].[Sigue] CHECK CONSTRAINT [FK_Sigue_Lista]
GO

ALTER TABLE [dbo].[Sigue]  WITH CHECK ADD  CONSTRAINT [FK_Sigue_UserData] FOREIGN     KEY([Usuario_IdUsuario])
REFERENCES [dbo].[UserData] ([Id])
GO

ALTER TABLE [dbo].[Sigue] CHECK CONSTRAINT [FK_Sigue_UserData]
GO

【问题讨论】:

null 不是有效的外键 - 错误消息有什么不清楚的地方? @PrestonGuillot 错误消息在哪里说明null 标题说值为空。错误消息表明该值违反了外键约束。 @PrestonGuillot 与空列无关。必须是其他人之一。您可以将 null 插入到 FK 列中,并且不要求在关系的另一端存在 null。 桌面上有触发器吗?您还可以编写包含外键的完整创建表吗? 【参考方案1】:
ALTER TABLE [dbo].[Sigue]  
WITH CHECK ADD  CONSTRAINT [FK_Sigue_Lista] FOREIGN KEY([IdSigue])
REFERENCES [dbo].[Lista] ([IdLista])

应该是

ALTER TABLE [dbo].[Sigue]  
WITH CHECK ADD  CONSTRAINT [FK_Sigue_Lista] FOREIGN KEY(Lista_IdLista)
REFERENCES [dbo].[Lista] ([IdLista])

您正在验证错误的列。目前的行为是它将验证IdSigue 中的值是否出现在[dbo].[Lista] 中。这不是正确的语义。

您的大多数其他 FK 定义中也会出现相同的错误。

【讨论】:

我没有注意到这一点。我修复了它,现在它没有显示任何错误消息,但表中也没有插入任何内容。 @JavierGonzález 可能是在您没有提交的交易中。 我不知道发生了什么,重新启动了我的计算机,现在我的代码可以工作了:D 谢谢谢谢谢谢:D【参考方案2】:

尝试将两列显式设置为NULL,如下所示:

INSERT INTO Sigue (Usuario_IdUsuario, Artista_IdArtista, Disco_IdDisco, Lista_IdLista) VALUES (@usu, @Artista, NULL, NULL);

根据以下链接,这应该可以工作:set null value in a foreign key column?Can table columns with a foreign key be null?

由于您提到该列没有设置默认值,您也可以尝试将默认值设置为NULL

您可以在这个小SQL Fiddle 中看到,将NULL 插入外键根本不是问题。

问题编辑后: 现在,您提供有关如何创建外键的信息:您正在同一列 IdSigue 上创建所有四个外键。

ALTER TABLE 语句应更改为:

ALTER TABLE [dbo].[Sigue]
  WITH CHECK ADD  CONSTRAINT [FK_Sigue_Artista]
  FOREIGN KEY([IdSigue]) REFERENCES [dbo].[Artista] ([IdArtista])

到:

ALTER TABLE [dbo].[Sigue]
  WITH CHECK ADD  CONSTRAINT [FK_Sigue_Artista]
  FOREIGN KEY([Artista_IdArtista]) REFERENCES [dbo].[Artista] ([IdArtista])

区别在于()后面的FOREIGN KEY

对其他三个外键定义也这样做。

最后但并非最不重要的几个链接:How do I create a foreign key in SQL Server?http://www.sqlinfo.net/sqlserver/sql_server_Create_foreign_key_contraints.php

【讨论】:

您能否在您的问题中发布您对SigueCREATE TABLE 声明?也许尝试这样的事情来创建它:***.com/questions/21547/… Noob 问题:如何在此处发布代码以保持代码的格式? 注释代码太多。编辑您的问题并将其放入其中! 你为什么要在外键列中出现 null 呢?那么外键的用途是什么。 外键的目的是确保,如果列设置为 NOT NULL,则该值必须指向另一个表中的行。外键也是同样的道理,不允许 NULL...

以上是关于当插入为 NULL 时,“INSERT 语句与 FOREIGN KEY 约束冲突”的主要内容,如果未能解决你的问题,请参考以下文章

当字符串为空时将 NULL 插入 SQL

当日期为空时,在访问中的日期列中插入空值

当 add_column 使用默认选项并且没有 null:false 时是不是有可能插入 null

当我将图像插入 MySQL 表时,结果为 NULL

C# - 将 null 插入 SQL Compact Edition 表

休眠奇怪的“ORA-01400:无法将 NULL 插入”错误