【问题标题】:MySQL Inserting into table with 2 foreign keysMySQL使用2个外键插入表
【发布时间】:2015-06-09 00:43:00
【问题描述】:

我正在开发一个使用 MySQL 数据库的 C# 应用程序。我正在尝试使用 2 个外键插入一个表,但出现错误:

无法添加或更新子行:外键约束失败 (thedatabase.tblC, CONSTRAINT tblC_ibfk_1 FOREIGN KEY (ID) REFERENCES tblA (ID) ON DELETE NO ACTION ON更新级联)

表结构是

tblA - ID、col2、col3、col4...

tblB - ID、col2、col3、col4...

tblC - tblA.ID、tblB.ID、col3、col4、col5...

我一直在查看论坛,但在我的一生中,我找不到使它起作用的语法。

这是我用来连接的。我已确认 ID 存在于父表中。

//Connect to the database
MySqlConnection connection = new MySqlConnection(connectionString);
MySqlCommand cmd;
connection.Open(); 

//Insert new record into database
cmd = connection.CreateCommand();
cmd.CommandText = "INSERT INTO tblC(tblA_ID, tblB_ID, col3, col4, col5) VALUES(@tblA_ID, @tblB_ID, @col3, @col4, @col5);";
cmd.Parameters.AddWithValue("@tblA_ID", tblA_ID);
cmd.Parameters.AddWithValue("@tblB_ID", tblB_ID);
cmd.Parameters.AddWithValue("@col3", col3);
cmd.Parameters.AddWithValue("@col4", col4);
cmd.Parameters.AddWithValue("@col5", col5);

cmd.ExecuteNonQuery();
connection.Close();

【问题讨论】:

  • 尝试发布一些代码以及错误消息。你在使用实体框架吗?它是一个网络应用程序吗?
  • 不是一个网络应用,只是一个普通的 C# 应用。该数据库旨在稍后与本地 Web 应用程序共享(使用 mysql 的原因)。
  • 你试过手动运行sql吗?

标签: c# mysql database


【解决方案1】:

您的语法没有问题,但外键错误表明存在数据问题。

发生错误是因为被引用的 ID 在 tblA 中不存在。

所以如果你正在做类似的事情:

INSERT INTO tblC SET tblA_id = 100, tblB_id = 101

tblA 必须有一条 ID = 100 的记录,tblB 必须有一条 ID = 101 的记录,否则会发生外键错误。

【讨论】:

    【解决方案2】:

    必须先添加外来记录;对所有插入使用事务以确保一致性。

    这是因为 MySQL does not support deferred FK constraints,但是 SQL Server 也没有..

    与一般的 MySQL 一样,在插入、删除或更新许多行的 SQL 语句中,InnoDB 逐行检查 UNIQUE 和 FOREIGN KEY 约束。在执行外键检查时,InnoDB 在它必须查看的子记录或父记录上设置共享行级锁。 InnoDB 立即检查外键约束;检查不推迟到事务提交。 ..

    (此外,对于代理/自增 PK,如何访问尚不存在的 ID?)

    可以使用LAST_INSERT_ID 和以下 SQL 来说明插入这样的关系:

     BEGIN TRANSACTION;
    
     DECLARE a_id INT DEFAULT 0,
             b_id INT DEFAULT 0;
    
     INSERT INTO tblA (..) VALUES (..)
     SET a_id = LAST_INSERT_ID();
    
     INSERT INTO tblA (..) VALUES (..)
     SET b_id = LAST_INSERT_ID();
    
     INSERT INTO tblC (..) VALUES (@a_id, @b_id, ..)
    
     COMMIT;
    

    从客户端进行插入时必须遵循完全相同的方法。创建国外记录;获取 ID,使用依赖记录中的 ID。

    对于“通用”ADO.NET 解决方案,可以将 ExecuteScalar 的结果用于插入 along with a trailing select(因数据库而异)。如果使用来自 MySqlConnector 的 MySqlCommand,则为 is natively supported via LastInsertedId

    当使用另一个框架和/或 ORM 时,请遵循其中用于构建对象图和/或确定插入的 ID 的规则。

    【讨论】:

      猜你喜欢
      • 2019-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 2020-02-28
      相关资源
      最近更新 更多