如何使用复合主键将值插入到 table 中?

How can I insert values into a table with a composite primary key?

这些是我已有的 table:

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

问题是每次我尝试向 table 添加新值(像这样)

INSERT INTO FcsGyartjaGya (Ar) VALUES (300);

我收到一条错误消息,提示我没有初始化 CsID INT 列:

Cannot insert the value NULL into column 'CsID', table 'Lab3.dbo.FcsGyartjaGya'; column does not allow nulls. INSERT fails.

我知道我必须用一些东西初始化它,但我不知道用它做什么,因为 IDENTITY(x, y) 不起作用(它已经被另一列占用)并向代码添加另一个参数(像这样)

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

创建另一个错误

The INSERT statement conflicted with the FOREIGN KEY constraint "FK_FcsGyartjaGya1". The conflict occurred in database "Lab3a", table "dbo.Gyartok", column 'GyID'.

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

我觉得有点混乱,如果我理解正确你想做什么,那么你有两个 tables 每个都有自己的 id,它基于一个标识列,所以您可以免费获得新的价值。 然后你试图用额外的数据建立关系table。

问题 1:如果 FcsGyartjaGya.GyID 引用 Gyartok.GyID,则不能将其作为身份,因为您将要插入其中而不是依赖于自动递增。如果它指的不是同一个,它应该有另一个名字,否则我的头可能会爆炸:))

问题 2:填充关系时 table 你需要插入你想要的对,SQL 服务器无法知道它应该如何匹配关系中的这些身份对table

我认为这就是人们在评论中的目标,例如 在行与 Focicsuka.CsID = 1 到 Gyartok.GyID 7 之间插入关系并添加 Ar = 300 必须看起来像

INSERT INTO FCSGYARTJAGYA(GYID, CSID, AR)
VALUES(7, 1, 300)

除非您忘记提及您想要为某些值中的每一个设置一些值或基于可以编写脚本的东西,换句话说,除非您有定义对及其值的逻辑,关系tables 的外键字段不能有默认值。

正如我在评论中提到的,如果星星正确对齐,您的 INSERT 将正常工作。对于你的 table Gyartok 你有 GyID 作为你的 PRIMARY KEY,它被定义为 IDENTITY(2,3);所以生成的第一个值是 2 然后每一行 尝试 INSERTed 将递增 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));

现在让我们为您的其他人添加一些数据 table:

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变成tableFcsGyartjaGya,定义如下:

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 个外键,在 GyIDCsID 上,当我们 INSERT 行时,值必须出现在各自的 table 中。然而,由于 GyID 被定义为 IDENTITY(3,2),因此我们需要依靠 the Stars 运气来使 INSERT 发挥作用。为什么? 2 + (3*n)3+(2*n) 可以给出非常不同的数字。第一个是您在本答案开头看到的。对于后者,我们有 357911 等数字。如您所见,这些数字中只有三分之一与我们原始序列中的数字匹配,所以我们要依靠运气。

因此,让我们尝试单个 INSERT

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

The INSERT statement conflicted with the FOREIGN KEY constraint "FK_FcsGyartjaGya1". The conflict occurred in database "Sandbox", table "dbo.Gyartok", column 'GyID'.

好吧,这没有用,但这是意料之中的。 3 不是 table Gyartok 中的值。我们再试一次!

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

成功了! 星星幸运在我们身边,IDENTITY值是tableGyartok中的一个值。这次我们试试几行吧!

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

The INSERT statement conflicted with the FOREIGN KEY constraint "FK_FcsGyartjaGya1". The conflict occurred in database "Sandbox", table "dbo.Gyartok", column 'GyID'. No!! Not again. :( That's because the stars didn't align; 7 and 9 aren't in the other table. But wait, 11 was in the sequence, so let's try that:

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

又出错了?!不,这不可能!!! :( 哦等等,我忘了,星星之前反对我们,因为 INSERTGyartok 的价值 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);

现在我们的 table 中又多了一行。


那么问题是什么?你的设计。 GyID定义为一个IDENTITY一个FOREIGN KEY;这意味着您在 SQL 服务器的“心血来潮”中生成了一个有效值。这不是你想要的。只是不要将列定义为 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);

所有这些行都可以正常插入。