【发布时间】:2012-04-08 21:03:26
【问题描述】:
我正在使用 MySQL 和 InnoDB,最近遇到了一些问题。
这是我正在尝试运行的语句(我删除了一些个人详细信息):
START TRANSACTION;
SET FOREIGN_KEY_CHECKS = 0;
INSERT INTO zdb_user (U_DateStart, U_Main_Adres_ID)
VALUES ('2012-04-08', 0);
SET FOREIGN_KEY_CHECKS = 1;
SET @newUID = LAST_INSERT_ID();
INSERT INTO zdb_adres (A_User_ID, A_Zipcode, A_Number)
VALUES (@newUID, '1234AB', 12);
UPDATE zdb_user SET U_Main_Adres_ID = LAST_INSERT_ID() WHERE User_ID = @newUID;
COMMIT;
问题是我使用的是“圆形”外键引用。我现在通过禁用密钥检查绕过了它。
zdb_adres.A_User_ID 需要有效的User_ID。而zdb_user.U_Main_Adres_ID 需要一个有效的Adres_ID,但我没有任何一个。现在,只要可以实际创建 zdb_user 中的记录,这一切都可以正常工作。但是有几个限制可能导致它无法创建。
我认为如果出现错误,事务会停止,但在运行一个简单的测试后,我发现这根本不是真的。因此我去谷歌搜索,我发现了几个解决方案,例如:
DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING, NOT FOUND BEGIN ROLLBACK; CALL ERROR_ROLLBACK_OCCURRED; END;
太糟糕了,它不起作用,当我在 START TRANSACTION; 之后添加它时收到语法错误:
1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING, NOT FOUND BEGIN ROLLBACK' at line 1
有人知道问题出在哪里吗?
【问题讨论】:
-
为什么不给自己一个受伤的世界,摆脱循环引用呢?一个 address_User 表将摆脱所有这些痛苦,这极大地违反了 KISS 原则。
-
那会更简单吗?它首先不能确保数据的有效性,它会引入多对多的可能性,这不是这样的。这是一对多的关系。
-
问一个关于如何避免循环引用的问题,我很乐意尝试回答。鉴于我现在不知道你对模型的所有标准,我不能肯定,但就个人而言,我会竭尽全力避免你现在所处的裂缝。
-
解决方案很简单,删除使 id 可以为空,一切正常。但是,如果该字段为 NULL,则会出现错误。所以它仍然必须在一个错误回滚的事务中。
-
那不是一个解决方案吗?在 Userid 上具有唯一键的 Address_user 是我的第一个想法....
标签: mysql sql transactions foreign-keys innodb