在空表中查找SQLite列名称

对于踢我写一个“架构文档”工具,生成一个数据库中的表和关系的描述。 目前我正在使用它来与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中的这种types的模式信息?

我觉得必须有一个隐藏的sqlite_xxx表隐藏在某个地方包含这个信息,但到目前为止还没有能够find它。

 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 

执行查询:

 PRAGMA table_info( your_table_name ); 

文档

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; }); 

@pragmanatu提出的PRAGMA语句也可以通过任何编程接口正常工作。 或者, sqlite_mastersql列具有描述表的SQL语句CREATE TABLE &c &c (但是,您必须parsing该表,因此我认为PRAGMA table_info更实用;-)。

执行这个查询

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

你可以在网上的sqlite引擎尝试

如果您起诉SQLite 3.8.3或更高版本(支持WITH子句),则此recursion查询应该适用于基本表。 在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);