【问题标题】:how can I check foreign key constrain on delete restrict using PHP如何使用 PHP 检查删除限制的外键约束
【发布时间】:2013-10-30 15:15:57
【问题描述】:

我有两个表 Productpurchase。 我在product.purchase_id 列和purchase.purchase_id 列中设置了一个on delete restrict FK。然后,如果我尝试使用 FK 删除 product.product_id,它会显示错误,就像

发生数据库错误 错误号:1451 无法删除或更新父行:外键约束失败(`another_bata`.`product_purchase_item`, CONSTRAINT `FK_product_purchase_item_1` FOREIGN KEY (`product_id`) REFERENCES `product` (`product_id`) ON UPDATE CASCADE) 从 product_id='158' 的产品中删除 文件名:C:\xampp\htdocs\rima_shoe\system\database\DB_driver.php 行号:330

但我需要一个用户友好的错误假设 你不能删除这个产品 列表,因为你已经有这个产品了

所以我需要在 php 中检查这个 FK,我该怎么做?

我的第二个问题.. 在某些特殊情况下是否可以删除已经存在 on delete restrict FK 的“product.product_id”?假设

DELETE p,q FROM product AS p INNER JOIN purchase AS q
WHERE p.purchase_id=q.purchase_id AND q.purchase_quan=0

【问题讨论】:

    标签: php mysql sql database


    【解决方案1】:

    使用例外:

    try {
        $db->query(...);
    } catch (Exception $e) {
        echo "an error occured during query";
    }
    

    您还可以创建自己的异常来专门针对 FK 错误:

    class ForeignKeyException extends Exception {
        public function __construct($msg = 0, $code = 0) {
            parent::__construct($msg, $code);
        }
    }
    

    发生FK错误时,你做throw new ForeignKeyException('FK failed');

    try {
        $db->query(...);
    } catch (ForeignKeyException $e) {
        echo "FK error";
    } catch (Exception $e) {
        echo "general error";
    }
    

    更新:

    mysqli 已经有异常了:

    } catch (mysqli_sql_exception $e) {
        if ($e->getCode() == 'CODE FOR FK') {
            //...
        }
    }
    

    PHP mysqli 异常:http://php.net/manual/en/class.mysqli-sql-exception.php

    查看 MYSQLI 错误代码:http://dev.mysql.com/doc/refman/5.6/en/error-messages-server.html

    另一个有用的问题:Handling foreign key exceptions in PHP

    第二个问题的更新:

    通过

    禁用外键
    SET foreign_key_checks = 0;
    <your delete query here>
    SET foreign_key_checks = 1;
    

    【讨论】:

      【解决方案2】:

      关于你的第二个问题,我想你可以用 php 检查条件,如果为真,运行这个查询:

      START TRANSACTION
      SET FOREIGN_KEY_CHECKS=0;
      DELETE WHAT YOU WANT;
      SET FOREIGN_KEY_CHECKS=1;
      COMMIT
      

      但是外键的存在是有原因的,随意玩弄它们迟早会给你带来惊喜

      【讨论】:

      • 我可以知道吗?为什么你使用TRANSANCTION 来临时禁用 FK,这可能是其他 FK 在这个时候会发生什么.. 猜猜有 20+ FK 当我运行这个查询............
      • 这只是一种确保所有步骤都成功的方法,如果一个步骤失败了,什么都不会发生。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-09
      • 2020-09-20
      • 2020-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多