测试特定id是否在任何外表条目中用作外键

时间:2011-10-01 04:19:11

标签: php mysql database foreign-keys

我有一个表'用户',列'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)

正如我已经提到的,在一个查询中包含所有内容会很好。但据我所知,这是不可能的......

......或者您有什么建议吗?

1 个答案:

答案 0 :(得分:0)

在纯SQL中无法做到这一点。但是,许多数据库都允许执行" dynamic"查询使用他们的过程语言(如T-SQL,PL-SQL等)。但这实际上只是你在php中做过的另一种方式。

另一种可能性,如果你对所有这些外键有良好的约束,并且它们不会级联删除,那就是制作行的备份副本,尝试删除它,并捕获将发生的错误如果这是一个约束违规。如果没有错误,您必须恢复数据。我认为,这只是一个理论上的想法。

最后,您可以保持活动引用计数,或者在了解外键关系的情况下提前编写查询。