我正在编写一个PHP应用程序,其中用户可以从列表中选择一个项目进行删除,但我想在尝试删除之前检查约束。然后,我可以提前突出显示这些项目,提醒用户约束。我可以创建所有约束的程序列表并通过PHP进行检查,但是如果在线下,在数据库端添加了其他约束呢?然后我需要在程序中定义这些新约束。
基本上,是否存在可以在不实际尝试删除并捕获错误的情况下运行的约束检查查询?
答案 0 :(得分:0)
据我所知,本身没有“DELETE CHECK”命令。
我的方法是扫描MySQL中的INFORMATION_SCHEMA
表,其中记录了外键关系。通过这些,可以生成SQL以检查删除是否会违反任何约束。
答案 1 :(得分:0)
有没有人发现像这样的解决方案有任何问题?我建议使用schtever建议使用information_schema数据。我已将此方法添加到我的数据库类中,并且从一些简单的测试中,它似乎可以工作。如果在匹配约束的任何数据库表中找到传递给它的密钥,它将告诉我第一个约束失败。如果任何表中没有键匹配,则返回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