我正在编写一个PHP应用程序,其中用户可以从列表中选择一个项目进行删除,但我想在尝试删除之前检查约束。然后,我可以提前突出显示这些项目,提醒用户注意约束。我可以制作所有约束的编程列表,并通过PHP进行检查,但如果在数据库端添加了其他约束怎么办?然后我需要在程序中定义这些新的约束。
基本上,是否有一个约束检查查询,可以运行而不实际尝试删除和捕获错误?
据我所知,本质上没有"DELETE CHECK"命令。
我的方法是扫描MySQL中记录外键关系的INFORMATION_SCHEMA
表。从这些,可以生成SQL来检查删除是否会违反任何约束。
有人看到这样的解决方案有什么问题吗?我根据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