对于踢,我正在编写一个“模式文档”工具,用于生成数据库中表和关系的描述。我目前正在使用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
表潜伏在包含此信息的地方,但到目前为止还无法找到它。
答案 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)
答案 2 :(得分:4)
执行此查询
select * from (select "") left join my_table_to_test b on -1 = b.rowid;
尝试
答案 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);