这些是我已经拥有的表格:
CREATE TABLE Gyartok
(
GyID INT IDENTITY(2, 3),
Nev VARCHAR(20),
CONSTRAINT PK_Gyartok PRIMARY KEY (GyID)
)
CREATE TABLE Focicsuka
(
CsID INT IDENTITY(2, 2),
Meret INT,
CONSTRAINT PK_Focicsuka PRIMARY KEY (CsID)
)
CREATE TABLE FcsGyartjaGya
(
GyID INT IDENTITY(3, 2),
CsID INT,
Ar INT,
CONSTRAINT FK_FcsGyartjaGya1
FOREIGN KEY (GyID) REFERENCES Gyartok(GyID),
CONSTRAINT FK_FcsGyartjaGya2
FOREIGN KEY (CsID) REFERENCES Focicsuka(CsID),
CONSTRAINT PK_FcsGyartjaGya
PRIMARY KEY (GyID, CsID)
)
问题是每次我尝试向表添加新值时(就像这样)
INSERT INTO FcsGyartjaGya (Ar) VALUES (300);
我收到一条错误消息,指出我没有初始化 CsID INT 列:
无法将值 NULL 插入到列 'CsID' 中,表 'Lab3.dbo.FcsGyartjaGya';列不允许空值。插入失败。
我知道我必须用一些东西初始化它,但我不知道如何处理它,因为IDENTITY(x, y)
不起作用(它已经被另一列占用)并向代码添加另一个参数(像这样)
INSERT INTO FcsGyartjaGya (Ar, CsID) VALUES (300, 7);
创建另一个错误,其中显示
INSERT 语句与外键约束"FK_FcsGyartjaGya1"冲突。冲突发生在数据库"Lab3a",表"dbo"中。嘉尔托克","GyID"一栏。
重要的是要注意,我已经用数据填充了每一列,所以这不是问题。
正如我在评论中提到的,只要星星正确对齐,您的INSERT
就可以正常工作。对于您的表Gyartok
,您将GyID
作为您的PRIMARY KEY
,定义为IDENTITY(2,3)
;因此,生成的第一个值是2
,然后尝试INSERT
的每一行 ed 将递增3
.
因此,如果我们运行以下命令,我们将获得 ID 2、5、7 和 17。(11 和 14 因INSERT
失败而跳过)。
CREATE TABLE Gyartok (
GyID INT IDENTITY(2, 3),
Nev VARCHAR(20),
CONSTRAINT PK_Gyartok PRIMARY KEY (GyID)
);
GO
INSERT INTO dbo.Gyartok (Nev)
VALUES ('asdfjahsbvd'),
('ashjkgdfakd'),
('kldfbhjo');
GO
INSERT INTO dbo.Gyartok (Nev)
VALUES (REPLICATE('A',25)), --Force a truncation error
('ashjkgdfakd');
GO
INSERT INTO dbo.Gyartok (Nev)
VALUES (REPLICATE('A',15));
现在让我们为您的其他表添加一些数据:
CREATE TABLE Focicsuka (
CsID INT IDENTITY(2, 2),
Meret INT,
CONSTRAINT PK_Focicsuka PRIMARY KEY (CsID)
)
INSERT INTO dbo.Focicsuka (Meret)
VALUES(12),
(25);
现在我们要INSERT
表FcsGyartjaGya
,定义为如下:
CREATE TABLE FcsGyartjaGya (
GyID INT IDENTITY(3, 2),
CsID INT,
Ar INT,
CONSTRAINT FK_FcsGyartjaGya1 FOREIGN KEY (GyID) REFERENCES Gyartok(GyID),
CONSTRAINT FK_FcsGyartjaGya2 FOREIGN KEY (CsID) REFERENCES Focicsuka(CsID),
CONSTRAINT PK_FcsGyartjaGya PRIMARY KEY (GyID, CsID)
)
这在GyID
上有一个IDENTITY
,但定义为IDENTITY(3,2)
,所以第一个值是3
然后递增2
。
由于它有 2 个外键,因此当我们INSERT
行时,GyID
和CsID
时,值必须出现在相应的表中。然而,由于GyID
被定义为IDENTITY(3,2)
,这就是我们需要依靠星星运气来INSERT
工作的地方。为什么?好吧,2 + (3*n)
和3+(2*n)
可以给出非常不同的数字。第一个是你在这个答案的开头看到的。对于后者,我们有像3
、5
、7
、9
、11
这样的数字。如您所见,这些数字中只有三分之一与我们原始序列中的数字匹配,因此运气是我们将要依赖的。
因此,让我们尝试一个INSERT
。
INSERT INTO dbo.FcsGyartjaGya (CsID,Ar)
VALUES(2,1);
INSERT 语句与外键约束"FK_FcsGyartjaGya1"冲突。冲突发生在数据库"沙盒"中,表"dbo。嘉尔托克","GyID"一栏。
好吧,这不起作用,但这是意料之中的。3
不是表中的值Gyartok
。让我们再试一次!
INSERT INTO dbo.FcsGyartjaGya (CsID,Ar)
VALUES(2,2);
成功了!星星运气是我们这边,IDENTITY
值是表Gyartok
中的值。这次让我们尝试几行!
INSERT INTO dbo.FcsGyartjaGya (CsID,Ar)
VALUES(4,3),
(4,4);
INSERT 语句与外键约束"FK_FcsGyartjaGya1"冲突。冲突发生在数据库"沙盒"中,表"dbo。嘉尔托克","GyID"一栏。
不!!又来了。:(那是因为星星没有对齐;7
和9
不在另一个表中。但是等等,11
在序列中,所以让我们尝试一下:
INSERT INTO dbo.FcsGyartjaGya (CsID,Ar)
VALUES(4,5);
又是错误?!不,不可能!!:(哦,等等,我忘了,星星以前反对过我们,因为那个INSERT
为了11
的价值而对Gyartok
失败了.我需要等17
!
--13 fails
INSERT INTO dbo.FcsGyartjaGya (CsID,Ar)
VALUES(4,6);
GO
--15 fails
INSERT INTO dbo.FcsGyartjaGya (CsID,Ar)
VALUES(4,6);
GO
--17 works!
INSERT INTO dbo.FcsGyartjaGya (CsID,Ar)
VALUES(4,6);
现在我们的表中还有另一行。
那么问题出在哪里?您的设计。GyID
被定义为IDENTITY
和FOREIGN KEY
;这意味着您处于SQL Server生成有效值的"突发奇想"。这不是你想要的。只是不要将列定义为IDENTITY
然后INSERT
定义了所有 3 列的数据:
CREATE TABLE FcsGyartjaGya (
GyID int,-- IDENTITY(3, 2),
CsID INT,
Ar INT,
CONSTRAINT FK_FcsGyartjaGya1 FOREIGN KEY (GyID) REFERENCES Gyartok(GyID),
CONSTRAINT FK_FcsGyartjaGya2 FOREIGN KEY (CsID) REFERENCES Focicsuka(CsID),
CONSTRAINT PK_FcsGyartjaGya PRIMARY KEY (GyID, CsID)
)
GO
INSERT INTO dbo.FcsGyartjaGya (GyID, CsID, Ar)
VALUES(2,2,1),
(2,4,2),
(5,4,3),
(8,2,4),
(8,4,5);
所有这些行都插入得很好。
我认为有点混乱,如果我正确理解您要做什么,那么您有两个表,每个表都有自己的id,该ID基于标识列,因此您可以免费获得新值。 然后,您正在尝试使用额外数据制作关系表。
问题 1:如果 FcsGyartjaGya.GyID 引用 Gyartok.GyID,则不能将其作为标识,因为您需要插入其中而不依赖于自动增量。如果它不是指相同的,它应该有另一个名字,否则我的头可能会爆炸:))
问题 2:填充关系表时,您需要插入所需的对,SQL Server 无法知道它应该如何匹配关系表中的这些标识对
我认为这就是人们在评论中的目标,例如 将行与 Focicsuka.CsID = 1 插入到 Gyartok.GyID 7 之间的关系,并添加 Ar = 300 必须看起来像
INSERT INTO FCSGYARTJAGYA(GYID, CSID, AR)
VALUES(7, 1, 300)
除非您忘记提及要为每个值或基于可以编写脚本的内容放置一些值,否则除非您有逻辑来定义对及其值,否则关系表不能在其外键字段上具有默认值。