【问题标题】:SQLite list ALL foreign keys in a databaseSQLite 列出数据库中的所有外键
【发布时间】:2019-12-04 19:19:44
【问题描述】:

有没有办法列出 SQLite 数据库中的所有外键?

它们似乎没有存储在 sqlite_master 中,PRAGMA foreign_key_list('table') 一次只列出一个。

或者,有没有办法列出哪些外键引用了一个表?

【问题讨论】:

    标签: sqlite


    【解决方案1】:

    似乎所有(或许多)PRAGMA 命令都可以通过一个小技巧以编程方式选择

    通常被称为:

    PRAGMA table_info('my_table');
    PRAGMA foreign_key_list('my_table');
    

    但这也可以做到:

    SELECT * FROM pragma_table_info('my_table');
    SELECT * FROM pragma_foreign_key_list('my_table');
    

    而且schema也可以(或多或少)获得:

    .schema pragma_table_info
    /* pragma_table_info(cid,name,type,"notnull",dflt_value,pk) */;
    
    .schema pragma_foreign_key_list
    /* pragma_foreign_key_list(id,seq,"table","from","to",on_update,on_delete,"match") */
    

    所以,让所有 fks 在sqlite_masterpragma_foreign_key_list 之间加入一个 JOIN 就可以了:

    SELECT 
        m.name
        , p.*
    FROM
        sqlite_master m
        JOIN pragma_foreign_key_list(m.name) p ON m.name != p."table"
    WHERE m.type = 'table'
    ORDER BY m.name
    ;
    

    请注意,pragma_foreign_key_list 的某些字段,例如 tablefrom、...必须被引用;

    【讨论】:

    • 你不能省略ON m.name != p."table",因为 SQLite 允许 (INNER) JOIN 而不打开? (将其视为 ON 1=1,就像在 CROSS JOIN 中一样。)
    • 称为 Natural Join 的 Afaik,其中 SQLite 自动测试两个表中存在的每一列的值之间的相等性。所以我认为这里不能省略ON。根据个人喜好,我更喜欢输入更多字符并明确说明正在发生的事情。
    【解决方案2】:

    使用 SQLite shell,使用 .schema 指令,并使用 GREP 过滤包含 REFERENCES 的行。

    来自SQLite仓库中的shell.c,主干今天的版本,两个查询:

    SELECT sql
      FROM (
            SELECT sql sql, type type, tbl_name tbl_name, name name
              FROM sqlite_master
             UNION ALL
            SELECT sql, type, tbl_name, name
              FROM sqlite_temp_master
           )
     WHERE tbl_name LIKE shellstatic()
       AND type != 'meta'
       AND sql NOTNULL
     ORDER BY substr(type, 2, 1), name
    

    SELECT sql
      FROM (
            SELECT sql sql, type type, tbl_name tbl_name, name name
              FROM sqlite_master
             UNION ALL
            SELECT sql, type, tbl_name, name
              FROM sqlite_temp_master
           )
     WHERE type != 'meta'
       AND sql NOTNULL
       AND name NOT LIKE 'sqlite_%'
     ORDER BY substr(type, 2, 1), name
    

    第二个可能就是你要找的。​​p>

    【讨论】:

    • 嗨,谢谢 Benoit。我应该提到我将在 android 客户端上执行此操作,因此无法访问 SQLite shell。 :(
    • 嗨,Benoit - 这为我提供了所有表的整个 ddl,这肯定很有用,但仍然让我遇到解析外键特定内容的问题。在“SELECT tbl_name FROM sqlite_master WHERE type = 'table'”的结果上调用 PRAGMA foreign_keys 对我来说可能会更容易,但我正试图找到一种更简单的方法来获得它?
    • @Fergal Moran:但这仍然是我能想到的最佳方式。
    • @FergalMoran:您描述的方式(从sqlite_master 获取表名,然后为每个表调用PRAGMA foreign_keys)是最简单的方式。不幸的是,PRAGMA 结果不能与 SELECT 语句结合......
    • 我认为列出表外键的正确命令是PRAGMA foreign_key_list,而不是PRAGMA foreign_keys
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多