web-dev-qa-db-ja.com

空のテーブルでSQLiteの列名を見つける

キックについては、データベースのテーブルとリレーションシップの説明を生成する「スキーマドキュメント」ツールを書いています。 SQLiteで動作するように調整しています。

_sqlite_master_テーブルに対するクエリを使用して、SQLiteデータベース内のすべてのテーブルの名前を抽出できました。次に、各テーブル名について、単純な

_select * from <table name>
_

クエリし、sqlite3_column_count() AP​​Iとsqlite3_column_name() AP​​Iを使用して列名を収集します。これをさらにsqlite3_table_column_metadata()にフィードして、追加情報を取得します。簡単ですよね?

問題は、空でないテーブルに対してのみ機能することです。つまり、sqlite_column_*() AP​​Iは、空のテーブルの場合とは異なり、sqlite_step()が_SQLITE_ROW_を返した場合にのみ有効です。

だから問題は、空のテーブルの列名をどのように見つけることができるのですか?または、より一般的には、SQLiteでこのタイプのスキーマ情報を取得するより良い方法はありますか?

この情報を含むどこかに潜んでいる別の隠された_sqlite_xxx_テーブルがなければならないように感じますが、これまでのところ、それを見つけることができませんでした。

36
Drew Hall
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
62
pragmanatu

クエリを実行します。

PRAGMA table_info( your_table_name );

ドキュメント

10

PRAGMA table_info( your_table_name );はHTML5 SQLiteでは機能しません。

空の場合でもyour_table_nameから列名を取得する小さなHTML5 SQLite JavaScriptスニペットは次のとおりです。お役に立てれば幸いです。

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

このクエリを実行する

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

online sqlite engine で試すことができます

4
user941581

@pragmanatuによって提案されたPRAGMAステートメントは、任意のプログラムインターフェイスでも正常に機能します。または、sqlite_mastersql列には、テーブルを説明するSQLステートメントCREATE TABLE &c &cがあります(ただし、これを解析する必要があるため、PRAGMA table_infoはもっと...実用的です;-)。

3
Alex Martelli

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);
0
user2812175