Trouver des noms de colonne SQLite dans la Table vide
pour le plaisir, j'écris un outil de "documentation schema" qui génère une description des tables et des relations dans une base de données. Je suis en train de le shimming pour travailler avec SQLite.
j'ai réussi à extraire les noms de toutes les tables dans une base de données SQLite via une requête sur le sqlite_master
tableau. Pour chaque nom de table, je tire alors un simple
select * from <table name>
requête, puis utilisez le sqlite3_column_count()
et sqlite3_column_name()
Api pour recueillir les noms de colonne, qui je le nourrir par la suite sqlite3_table_column_metadata()
pour obtenir des informations supplémentaires. Assez Simple, non?
Le problème est qu'il ne fonctionne que pour les tables qui ne sont pas vides. Qui est, le sqlite_column_*()
les API ne sont valides que si sqlite_step()
est de retour SQLITE_ROW
, qui n'est pas le cas pour les tables vides.
alors la question Est, Comment puis-je découvrir les noms de colonne pour les tables vides? Ou, plus généralement, est-il une meilleure façon d'obtenir ce type d'informations de schéma dans SQLite?
je me sens comme il doit être cachée sqlite_xxx
table rôdant quelque part contenant cette information, mais jusqu'à présent n'ont pas été en mesure de le trouver.
6 réponses
PRAGMA table_info( your_table_name );
ne fonctionne pas dans HTML5 SQLite.
voici un petit extrait de JavaScript HTML5 SQLite qui obtient les noms des colonnes de votre_name même si elle est vide. Espérons que c'est utile.
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, '').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;
});
exécutez cette requête
select * from (select "") left join my_table_to_test b on -1 = b.rowid;
Vous pouvez essayer en ligne moteur sqlite
PRAGMA
déclaration suggérée par @pragmanatu fonctionne très bien à travers n'importe quelle interface programmatique, aussi. Alternativement, le sql
colonne sqlite_master
a SQL
déclaration CREATE TABLE &c &c
qui décrit la table (mais, vous auriez à analyser qui, je pense donc que PRAGMA table_info
c'est plus... pragmatique.)-;
si vous poursuivez SQLite 3.8.3 ou plus tard (supporte la clause WITH), cette requête récursive devrait fonctionner pour les tables de base. On 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);