测试是不是在任何外部表条目中使用特定 id 作为外键

Posted

技术标签:

【中文标题】测试是不是在任何外部表条目中使用特定 id 作为外键【英文标题】:test if a specific id is used as foreign key in any foreign table entry测试是否在任何外部表条目中使用特定 id 作为外键 【发布时间】:2011-11-28 21:46:19 【问题描述】:

我有一个表“用户”,其中有一列“id”。 此 id 在许多其他表(如帖子、cmets 等)中用作外键。

我想知道在任何外部表中是否有指向特定用户 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】:

在纯 SQL 中无法做到这一点。然而,许多数据库确实允许使用它们的过程语言(如 T-SQL、PL-SQL 等)执行“动态”查询。但这实际上只是您在 php 中所做的另一种方式。

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

最后,您可以维护一个活跃的引用计数,或者在了解外键关系的情况下提前编写一个查询。

【讨论】:

以上是关于测试是不是在任何外部表条目中使用特定 id 作为外键的主要内容,如果未能解决你的问题,请参考以下文章

当我从具有其他外键的表中删除一个条目时,相应的记录也不会被删除

如何使用 Django 模型在 ExtJS 网格中获取外键值而不是键?

QTableview:根据其他列中的值显示特定列中的数据

如何在 Laravel 中定义和使用外键作为主键?

MYSQL:使用字母数字 ID 在特定值之后选择接下来的 100 行

如果任何列与另一个表中的匹配行不同,如何插入行