我有一个表'用户',列'id'。 此id在许多其他表(如帖子,评论等)中用作外键。
我想知道在任何外国表中是否有指向特定用户ID的链接。
这给了我所有表名和列名,表'users'中的列'id'用作外键:
SELECT table_name,column_name
FROM information_schema.key_column_usage
WHERE referenced_table_name = 'users';
现在,我如何测试我的特定用户ID是否在结果中的某个表/列中用作外键 - 并将此测试合并到上面的sql代码中以获得单个查询?
我找到了一个解决方案并将以下函数添加到我的php数据库类中:
/**
* isKeyUsedAsForeignKey
*
* returns true if the $key from column 'id' in $table is used as foreign key in other tables and there are one or more entries in one or more of this foreign tables with $key from $table in the respective foreign key column
*
* @param string $table table name
* @param int $key entry id
* @return bool
*/
public function isKeyUsedAsForeignKey( $table, $key ) {
$key = intval($key);
if( preg_match('/^[-_a-z0-9]+$/i',$table) && $key>0 ) {
$result = $this->query("SELECT table_name,column_name FROM information_schema.key_column_usage WHERE referenced_table_name = '".$table."'");
$select = array();
while( $result && $row=$result->fetch_assoc() )
array_push($select,"(SELECT COUNT(DISTINCT ".$row['column_name'].") FROM ".$row['table_name']." WHERE ".$row['column_name']."='".$key."') AS ".$row['table_name']);
$result2 = $this->query("SELECT ".implode(',',$select));
if( $result2 && $row=$result2->fetch_row() )
return array_sum($row)>0 ? true : false;
}
return false;
}
现在我可以运行以下测试来确定'users'中的id 3是否用作外键:
$db->isKeyUsedAsForeignKey('users',3)
正如我已经提到的,在一个查询中包含所有内容会很好。但据我所知,这是不可能的......
......或者您有什么建议吗?
答案 0 :(得分:0)
在纯SQL中无法做到这一点。但是,许多数据库都允许执行" dynamic"查询使用他们的过程语言(如T-SQL,PL-SQL等)。但这实际上只是你在php中做过的另一种方式。
另一种可能性,如果你对所有这些外键有良好的约束,并且它们不会级联删除,那就是制作行的备份副本,尝试删除它,并捕获将发生的错误如果这是一个约束违规。如果没有错误,您必须恢复数据。我认为,这只是一个理论上的想法。
最后,您可以保持活动引用计数,或者在了解外键关系的情况下提前编写查询。