【问题标题】:How to tell if a sqlite column is AUTOINCREMENT?如何判断一个 sqlite 列是否为 AUTOINCREMENT?
【发布时间】:2014-01-25 14:02:07
【问题描述】:

我正在使用一个 sqlite 数据库,我想知道一个特定的列是 AUTOINCREMENT 还是 NOT

我试过了

PRAGMA table_info('table name') ;

但它只给了我 ID、NAME、TYPE、PRIMARY KEY、NOT NULL 和 DEFAULT VALUE

【问题讨论】:

    标签: sql sqlite


    【解决方案1】:

    查询

    PRAGMA TABLE_INFO(yourtable);
    

    可以获取主键列名。

    判断是否为自增列,检查表是否有自增序列:

    SELECT COUNT(*) FROM sqlite_sequence WHERE name='yourtable';
    

    解读:

    • 如果计数结果为非零,则表有一个自动增量主键列。

    • 如果计数为零,则表为空且从未包含数据,或者没有自动增量主键列。

    虽然SQLite documentation 似乎暗示在创建表时填充了 sqlite_sequence 表,但实际上并非如此,并且计数仅在插入数据后才可用。

    【讨论】:

    • 如果表有自增主键列,sqlite_sequence中不应该总是有一个条目吗?
    • 这很方便,但您应该知道它不是防弹的。考虑创建表的情况,列是自动增量和主键——但表还没有任何记录。在这种情况下,依靠 COUNT 来判断该列是否为自增会导致误入歧途...
    • @Lara 是正确的,因为如果 CREATE 语句中的主键包含关键字 PRIMARY KEY AUTOINCREMENT 那么 sqlite_sequence 表中总会有一个条目,因此对于这种情况,您可以期望它是确定性的如果 count(*) 不为零。 sqlite.org/autoinc.html
    • 为我的编辑向@laalto 道歉,他的原始陈述是正确的并且已经恢复了解释。
    • 太伤心了,实际上没有办法告诉..对于一张空桌子。
    【解决方案2】:

    原谅我,因为我犯了罪:

    WITH RECURSIVE
      a AS (
        SELECT name, lower(replace(replace(sql, char(13), ' '), char(10), ' ')) AS sql
        FROM sqlite_master
        WHERE lower(sql) LIKE '%integer% autoincrement%'
      ),
      b AS (
        SELECT name, trim(substr(sql, instr(sql, '(') + 1)) AS sql
        FROM a
      ),
      c AS (
        SELECT b.name, sql, '' AS col
        FROM b
        UNION ALL
        SELECT 
          c.name, 
          trim(substr(c.sql, ifnull(nullif(instr(c.sql, ','), 0), instr(c.sql, ')')) + 1)) AS sql, 
          trim(substr(c.sql, 1, ifnull(nullif(instr(c.sql, ','), 0), instr(c.sql, ')')) - 1)) AS col
        FROM c JOIN b ON c.name = b.name
        WHERE c.sql != ''
      ),
      d AS (
        SELECT name, substr(col, 1, instr(col, ' ') - 1) AS col
        FROM c
        WHERE col LIKE '%autoincrement%'
      )
    SELECT name, col  
    FROM d
    ORDER BY name, col;
    

    此查询基于两个假设:

    1. autoincrement 标志出现在sqlite_master 内的列定义中
    2. 该列的类型为 integer(目前 SQLite 需要)

    由于正则表达式没有开箱即用,因此此查询使用递归方法来匹配所有列。请原谅我。

    当然……

    您也可以在某些客户端中简单地处理您的sqlite_master.sql 内容,例如一个 Java 程序,使用简单的正则表达式,如果这对你来说更容易的话。

    【讨论】:

      猜你喜欢
      • 2013-03-11
      • 2019-03-20
      • 2019-03-24
      • 2017-08-30
      • 2017-03-05
      • 1970-01-01
      • 1970-01-01
      • 2011-11-14
      • 1970-01-01
      相关资源
      最近更新 更多