【问题标题】:Identity conflict with inserting data与插入数据的身份冲突
【发布时间】:2016-04-14 07:40:18
【问题描述】:

我遇到了一个涉及在 MS SQL 服务器中运行 mySQL 代码的问题。 我使用身份在大多数表中自动增加 ID 号。例如:

CREATE TABLE klant (
    klantnr INTEGER identity (1, 1) PRIMARY KEY,
    bedrijfsnaam VARCHAR (50) NOT NULL
)

我正在尝试在我的登录表中插入此表中存在的相同“klantnr”值,该值被定义为 Klant 表的外键:

CREATE TABLE Logins (
    GebruikersNaam VARCHAR (30),
    Wachtwoord VARCHAR (30),
    Klantnr INT,
    MdwNr INT,
    CONSTRAINT pk_logID PRIMARY KEY (GebruikersNaam),
    CONSTRAINT fk_klantnr FOREIGN KEY (klantnr) REFERENCES klant (klantnr),
    CONSTRAINT fk_mdwnr FOREIGN KEY (mdwnr) REFERENCES medewerker (mdwnr)
)

以下是插页:

INSERT INTO klant VALUES ('Jumbo'); -- (this is the first insert, klantnr is 1)
INSERT INTO Logins VALUES ('KlantTest', 'test', 1, NULL);

错误:消息 547,级别 16,状态 0,行 302 INSERT 语句 与 FOREIGN KEY 约束“fk_klantnr”冲突。冲突 发生在数据库“DorblogisticsB31B”,表“dbo.klant”,列 'klantnr'。

我做错了什么?

【问题讨论】:

  • SELECT * FROM klant WHERE klantnr = 1 可能为空
  • @wero,不。第一个插入是 klantnr = 1。
  • 你看表了吗?
  • @wero,是的。 Klantnr = 1 Bedrijfsnaam = 'Jumbo'。
  • 删除你的表,重新运行创建表脚本,没有第三个约束。然后按顺序运行插入,语句就会运行。您收到该错误是因为它在父表中找不到匹配的“klantnr”。

标签: sql-server insert identity


【解决方案1】:

我很确定您忽略了一些非常小的问题,就像我们通常处理这些类型的错误一样,运行以下 sql 并查看是否得到相同的结果:(注意:不要尝试使用最佳实践或任何事情,只是想让你得到你的答案)

    IF OBJECT_ID('dbo.Logins', 'U') IS NOT NULL 
      DROP TABLE dbo.Logins; 

    IF OBJECT_ID('dbo.klant', 'U') IS NOT NULL 
      DROP TABLE dbo.klant; 

    CREATE TABLE klant (
        klantnr INTEGER identity (1, 1) PRIMARY KEY,
        bedrijfsnaam VARCHAR (50) NOT NULL
    )

    CREATE TABLE Logins (
        GebruikersNaam VARCHAR (30),
        Wachtwoord VARCHAR (30),
        Klantnr INT,
        MdwNr INT,
        CONSTRAINT pk_logID PRIMARY KEY (GebruikersNaam),
        CONSTRAINT fk_klantnr FOREIGN KEY (klantnr) REFERENCES klant (klantnr)
    )



    --re run this query 3 times...
    INSERT INTO klant VALUES ('Jumbo');
    INSERT INTO Logins VALUES ('KlantTest' + CONVERT(VARCHAR,(SELECT MAX(klantnr) FROM klant)),
                                 'test', 
                                 (SELECT MAX(klantnr) FROM klant) 
                                 , NULL);


    SELECT * FROM klant
    /*
    OUTPUT:
    1   Jumbo
    2   Jumbo
    3   Jumbo
    */
    SELECT * FROM Logins

    /*
    OUTPUT:
    KlantTest1  test    1   NULL
    KlantTest2  test    2   NULL
    KlantTest3  test    3   NULL
    */

【讨论】:

  • 是的.. 我尝试在 klant 数据之前插入登录数据。难怪它不起作用......无论如何,它是固定的:)
【解决方案2】:

解决方法 以下是解决此问题的两种方法: 将外键约束中使用的所有列定义为 NOT NULL。

-或-

在同一更新语句中更新外键约束中使用的所有列。

https://support.microsoft.com/en-us/kb/256307 https://dba.stackexchange.com/questions/62325/how-to-solve-the-error-msg-547-level-16-state-0-line-1

【讨论】:

    【解决方案3】:

    插入 [klant] 后试试这个:

    SELECT * FROM klant WHERE bedrijfsnaam='Jumbo'
    

    通过这种方式,您可以找出分配给“Jumbo”的 ID 号。然后使用此 ID,您可以将值插入 [logins]。

    【讨论】:

    • 当我执行该查询时,我得到:Klantnr = 1,Bedrijfsnaam = 'Jumbo'。然后当我进行插入时: INSERT INTO Logins VALUES ('KlantTest', 'test', 1, NULL);它不起作用,我得到了错误。
    • 错误信息和你上面发布的一样吗?您是否在 TRANSACTION 中编写查询?或者如果您的服务器上禁用了自动提交,则您的 INSERT 可能未提交。请在另一个会话中检查上述 SELECT。
    【解决方案4】:

    我修好了。这是有史以来最愚蠢的错误。我尝试在插入 klant 数据之前插入登录数据...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多