2009-05-30 3 views
35

Для пинков Я пишу инструмент «документации схемы», который генерирует описание таблиц и отношений в базе данных. Я в настоящее время shimming его для работы с SQLite.Найти имена столбцов SQLite в пустой таблице

Мне удалось извлечь имена всех таблиц в базе данных SQLite с помощью запроса в таблице sqlite_master. Для каждого имени таблицы, я тогда выстрелить простой

select * from <table name> 

запрос, а затем использовать sqlite3_column_count() и sqlite3_column_name() API, чтобы собрать имена столбцов, которые я также питающие к sqlite3_table_column_metadata(), чтобы получить дополнительную информацию. Достаточно просто, не так ли?

Проблема в том, что она работает только для таблиц, которые не пусты. То есть, API sqlite_column_*() действительны только в том случае, если sqlite_step() вернул SQLITE_ROW, что не относится к пустым таблицам.

Итак, вопрос в том, как узнать имена столбцов для пустых таблиц? Или, в более общем плане, есть ли лучший способ получить этот тип информации о схеме в SQLite?

Я чувствую, что здесь есть еще одна скрытая таблица sqlite_xxx, где-то содержащая эту информацию, но до сих пор не удалось ее найти.

+2

Спасибо всем. Я ошибочно считал, что интерфейс PRAGMA предназначен только для клиента командной строки 'sqlite3'. –

ответ

61
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 
+4

Похоже, что это работает в командной строке - как я могу добиться того же эффекта программно? –

+4

@pragmanatu - ваше прозвище совпадение? :) –

+0

Спасибо - это работало как шарм и намного проще, чем то, что я делал. Ура! –

3

PRAGMA заявление было предложено @pragmanatu отлично работает через любой программный интерфейс тоже. В качестве альтернативы, столбец sql от имеет оператор SQLCREATE TABLE &c &c, который описывает таблицу (но вам придется анализировать это, поэтому я думаю, что PRAGMA table_info более ... прагматично ;-).

3

выполнить этот запрос

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

Вы можете попробовать его на online sqlite engine

+0

Я пробовал это, это не сработало. – xApple

+0

этот способ лучший!Если вы не знаете имя столбца 'rowid', я предлагаю использовать:' SELECT t. * FROM (SELECT 1) LEFT JOIN table AS t LIMIT 1' – conca

4

PRAGMA table_info(your_table_name); не работает в HTML5 SQLite.

Вот небольшой фрагмент кода HTML5 SQLite JavaScript, который получает имена столбцов из вашего_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; 
}); 
+0

Похоже, если ваша таблица имеет более одного столбца, столбцы 2 - n не обрабатывается из-за ведущих пробелов. Это можно устранить, вызвав функцию 'trim()' в строке (или внедряя ее самостоятельно для браузеров, которые еще не поддерживают 'trim()'). Вызов вышеуказанной функции в таблице (Person) с полем ID и Name возвращает '[" id "," "]'. – legacybass

0

Если вы подали в суд SQLite 3.8.3 или более поздняя версия (поддерживает С п), это рекурсивный запрос должен работать для базовых таблиц. На 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); 
Смежные вопросы