在空表中查找SQLite列名称

时间:2009-05-30 02:51:34

标签: database sqlite schema

对于踢,我正在编写一个“模式文档”工具,用于生成数据库中表和关系的描述。我目前正在使用SQLite。

我设法通过sqlite_master表上的查询提取SQLite数据库中所有表的名称。对于每个表名,我然后触发一个简单的

select * from <table name>

查询,然后使用sqlite3_column_count()sqlite3_column_name() API收集列名称,我将其进一步提供给sqlite3_table_column_metadata()以获取其他信息。很简单,对吧?

问题是它只适用于非空的表。也就是说,sqlite_column_*() API仅在sqlite_step()返回SQLITE_ROW时有效,而空表不是这种情况。

所以问题是,如何发现空表的列名?或者,更一般地说,有没有更好的方法在SQLite中获取这种类型的架构信息?

我觉得必须有另一个隐藏的sqlite_xxx表潜伏在包含此信息的地方,但到目前为止还无法找到它。

6 个答案:

答案 0 :(得分:62)

sqlite> .header on
sqlite> .mode column
sqlite> create table ABC(A TEXT, B VARCHAR);
sqlite> pragma table_info(ABC);
cid         name        type        notnull     dflt_value  pk
----------  ----------  ----------  ----------  ----------  ----------
0           A           TEXT        0                       0
1           B           VARCHAR     0                       0

答案 1 :(得分:10)

执行查询:

PRAGMA table_info( your_table_name );

Documentation

答案 2 :(得分:4)

执行此查询

select * from (select "") left join my_table_to_test b on -1 = b.rowid;

您可以在online sqlite engine

尝试

答案 3 :(得分:4)

PRAGMA table_info( your_table_name );在HTML5 SQLite中不起作用。

这是一个小的HTML5 SQLite JavaScript代码段,它从your_table_name获取列名,即使它是空的。希望它有所帮助。

tx.executeSql('SELECT name, sql FROM sqlite_master WHERE type="table" AND name = "your_table_name";', [], function (tx, results) {
  var columnParts = results.rows.item(0).sql.replace(/^[^\(]+\(([^\)]+)\)/g, '$1').split(',');
  var columnNames = [];
  for(i in columnParts) {
    if(typeof columnParts[i] === 'string')
      columnNames.push(columnParts[i].split(" ")[0]);
  }
  console.log(columnNames);
  ///// Your code which uses the columnNames;
});

答案 4 :(得分:3)

@pragmanatu建议的PRAGMA语句也适用于任何编程接口。或者,sql的{​​{1}}列包含描述该表的sqlite_master语句SQL(但是,您必须对其进行解析,因此我认为CREATE TABLE &c &c更......务实; - )。

答案 5 :(得分:0)

如果您使用SQLite 3.8.3或更高版本(支持WITH子句),则此递归查询应适用于基本表。在CTAS,YMMV。

WITH
    Recordify(tbl_name, Ordinal, Clause, Sql)
AS
    (
     SELECT
        tbl_name,
        0,

        '',
        Sql
     FROM
        (
         SELECT
            tbl_name,
            substr
            (
             Sql,
             instr(Sql, '(') + 1,
             length(Sql) - instr(Sql, '(') - 1
            ) || ',' Sql
         FROM
            sqlite_master
         WHERE
            type = 'table'
        )
     UNION ALL
     SELECT
        tbl_name,
        Ordinal + 1,
        trim(substr(Sql, 1, instr(Sql, ',') - 1)),
        substr(Sql, instr(Sql, ',') + 1)
     FROM
        Recordify
     WHERE
        Sql > ''
       AND  lower(trim(Sql)) NOT LIKE 'check%'
       AND  lower(trim(Sql)) NOT LIKE 'unique%'
       AND  lower(trim(Sql)) NOT LIKE 'primary%'
       AND  lower(trim(Sql)) NOT LIKE 'foreign%'
       AND  lower(trim(Sql)) NOT LIKE 'constraint%'
    ),
    -- Added to make querying a subset easier.
    Listing(tbl_name, Ordinal, Name, Constraints)
AS
    (
     SELECT
        tbl_name,
        Ordinal,
        substr(Clause, 1, instr(Clause, ' ') - 1),
        trim(substr(Clause, instr(Clause, ' ') + 1))
     FROM
        Recordify
     WHERE
        Ordinal > 0
    )
SELECT
    tbl_name,
    Ordinal,
    Name,
    Constraints
FROM
    Listing
ORDER BY
    tbl_name,
    lower(Name);