如何将值插入到具有复合主键的表中?

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

这些是我已有的桌子:

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 值插入表“Lab3.dbo.FcsGyartjaGya”的“CsID”列;列不允许为空。插入失败。

我知道我必须用一些东西初始化它,但我不知道用什么来初始化它,因为

IDENTITY(x, y)
不起作用(它已经被另一列占用了)并向代码添加另一个参数(像这样)

INSERT INTO FcsGyartjaGya (Ar, CsID) VALUES (300, 7);

创建另一个错误,其中显示

INSERT 语句与 FOREIGN KEY 约束“FK_FcsGyartjaGya1”冲突。冲突发生在数据库“Lab3a”、表“dbo.Gyartok”、列“GyID”中。

需要注意的是,我已经在每一列中填充了数据,所以这不会是问题。

sql sql-server constraints sql-insert primary-key
2个回答
2
投票

正如我在评论中提到的,只要星星正确对齐,你的

INSERT
就能正常工作。对于您的表
Gyartok
,您将
GyID
作为您的
PRIMARY KEY
,其定义为
IDENTITY(2,3)
;因此生成的第一个值是
2
,然后每行 尝试
INSERT
都会增加
3

因此,如果我们运行以下命令,我们将获得 ID 2、5、7 和 17。(由于

INSERT
失败,因此会跳过 11 和 14)。

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)
)

这在

IDENTITY
上有一个
GyID
,但定义为
IDENTITY(3,2)
,因此第一个值是
3
,然后按
2
递增。

由于它有 2 个外键,因此当我们

GyID
行时,在
CsID
INSERT
上,值必须出现在各自的表中。然而,由于
GyID
被定义为
IDENTITY(3,2)
,因此我们需要依靠 the Stars 运气才能让
INSERT
发挥作用。为什么?那么
2 + (3*n)
3+(2*n)
可以给出非常不同的数字。第一个是您在本答案开头看到的。对于后者,我们有
3
5
7
9
11
等数字。正如您所看到的,这些数字中只有三分之一与我们原始序列中的数字匹配,因此我们将依赖运气。

因此,让我们尝试一个

INSERT

INSERT INTO dbo.FcsGyartjaGya (CsID,Ar)
VALUES(2,1);

INSERT 语句与 FOREIGN KEY 约束“FK_FcsGyartjaGya1”冲突。冲突发生在数据库“Sandbox”、表“dbo.Gyartok”、列“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 语句与 FOREIGN KEY 约束“FK_FcsGyartjaGya1”冲突。冲突发生在数据库“Sandbox”、表“dbo.Gyartok”、列“GyID”中。

不!!不会再有。 :( 那是因为星星没有对齐;

7
9
不在另一个表中。但是等等,
11
在序列中,所以让我们尝试一下:

INSERT INTO dbo.FcsGyartjaGya (CsID,Ar)
VALUES(4,5);

又出错了?!不,不可能! :(哦等等,我忘了,之前星星们都反对我们,因为

INSERT
因为
Gyartok
的价值而失败了
11
。我需要等待
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
a
FOREIGN KEY
;这意味着您可以随心所欲地由 SQL Server 生成一个有效值。这不是你想要的。只是不要将该列定义为
IDENTITY
,然后将定义了所有 3 列的数据定义为
INSERT

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);

所有这些行都插入得很好。


0
投票

我认为这有点混乱,如果我正确理解你想要做什么,那么你有两个表,每个表都有自己的 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)

除非您忘记提及您想要为每个值添加一些值或基于可以编写脚本的内容,换句话说,除非您有逻辑来定义对及其值,否则关系表不能具有默认值他们的外键字段。

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