简体   繁体   English

有没有一种方法可以在删除行之前检查MySql中的约束违规?

[英]Is there a way to check constraint violations in MySql before deleting a row?

I am writing a PHP application in which a user can select an item from a list for deletion, but I want to check the constraints BEFORE even attempting the delete. 我正在编写一个PHP应用程序,用户可以在其中选择要删除的项目,但是我想在尝试删除之前检查约束。 Then I can potentially highlight these items ahead of time alerting the user of the constraint. 然后,我可以提前突出显示这些项目,以提醒用户约束。 I could make a programatic list of all of the constraints and do the checks through PHP, but what if down the line, other constraints are added on the database side? 我可以列出所有约束的程序化列表,并通过PHP进行检查,但是如果在线下,其他约束又添加到数据库端怎么办? I would then need to define these new constraints in the program. 然后,我需要在程序中定义这些新的约束。

Basically, is there a constraint check query that can be run without actually trying the delete and catching the error? 基本上,是否有一个约束检查查询可以在不实际尝试删除和捕获错误的情况下运行?

As far as I know, there's no "DELETE CHECK" command, per se. 据我所知,本身没有“ DELETE CHECK”命令。

My approach would be to scan the INFORMATION_SCHEMA tables in MySQL, where the foreign key relationships are recorded. 我的方法是扫描MySQL中的INFORMATION_SCHEMA表,其中记录了外键关系。 From those, one could generate the SQL to check if a delete would violate any constraints. 从中可以生成SQL来检查删除是否违反任何约束。

Does anyone see any problem with a solution like this? 有没有人看到这样的解决方案有任何问题? I built this off of schtever's suggestion of using the information_schema data. 我是根据schtever建议使用information_schema数据建立的。 I have added this method to my database class, and from some simple tests, it seems to work. 我已经将此方法添加到我的数据库类中,并且通过一些简单的测试,它似乎可以工作。 It will tell me the first constraint that fails if the key passed to it is found in any of the database tables matching a constraint. 如果在任何与约束匹配的数据库表中找到传递给它的键,它将告诉我第一个失败的约束。 If there is no key match in any of the tables, it returns false indicating no constraints. 如果在任何一个表中都不存在键匹配,则返回false表示没有约束。

/**
 * hasDeleteConstraints - This method uses the MySQL information_schema information to check for
 *                        constraint violations. If violations are found, the method returns the
 *                        constraint name and the table name of where matching data is found.
 *
 * @param string $table The database table being checked
 * @param string $field The key field to check
 * @param string $value The value to search for
 *
 * @return mixed - The matching constraint data if found, false if no constraints found
 */
public static function hasDeleteConstraints($table, $field, $value) {
    $sql = "SELECT KCU.CONSTRAINT_NAME, KCU.TABLE_NAME, KCU.COLUMN_NAME
            FROM information_schema.KEY_COLUMN_USAGE KCU
            LEFT JOIN information_schema.REFERENTIAL_CONSTRAINTS REFC USING(CONSTRAINT_NAME)
            WHERE KCU.REFERENCED_TABLE_NAME = " . self::quote($table) . "
              AND KCU.REFERENCED_COLUMN_NAME = " . self::quote($field) . "
              AND REFC.DELETE_RULE = 'RESTRICT'
            GROUP BY KCU.CONSTRAINT_NAME";
    $result = self::dbQueryAll($sql);

    if ($result) {
        foreach ($result as $row) {
            $sql = "SELECT {$row['COLUMN_NAME']}
                    FROM {$row['TABLE_NAME']}
                    WHERE {$row['COLUMN_NAME']} = " . self::quote($value);
            if (self::dbQueryRow($sql) !== false) {
                return $row;
            }
        }
    }
    return false;
} //End public static function hasDeleteConstraints

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM