2016-01-17 2 views
1

Я использую инструмент оболочки SQLite3 для поддержки небольшой базы данных. Я использую флаги -header -ascii, хотя это применимо, насколько я могу судить, к любому из вариантов вывода. Я ищу способ избежать двусмысленности по типу возвращаемого значения. Рассмотрим следующий пример:Вывод типа значений, возвращаемых инструментом оболочки SQLite3

Create Table `things` (`number` Integer, `string` Text, `binary` Blob); 
Insert Into `things` (`number`,`string`,`binary`) Values (4,'4',X'34'); 
Select * From `things`; 

Это возвращает (с помощью caret notation):

number^_string^_binary^^4^_4^_4^^ 

Как видно, нет никакого способа определить тип любого из персонажей «4» из ответа в одиночку, поскольку ни один из них не имеет отличительных разделителей.

Есть ли способ принудить включение метаданных типа в ответ?

Я хотел бы избежать:

  • заявления изменяющих запросов также включают в себя тип, как было бы obfuscatory и был бы излишней в случае я сделал переключение интерфейсов;

  • предваряя TEXT и BLOB значения до вставки, как это должно было бы быть единым для всех TEXT и BLOB взаимодействия (говоря, что это еще мой предпочтительный выбор должен он прийти к этому).

Что я ищу это переключатель какой-то, что указывает на тип как часть ответа SQLite в и т.д .:

number^_string^_binary^^4^_'4'^_X'4'^^ 
number^_string^_binary^^4^_text:4'^blob:4^^ 

или какой-либо его вариации. Основополагающим для этого является только один ответ, содержащий достаточную информацию, чтобы различать тип и значение каждого элемента этого ответа (так же, как и в API-интерфейсе библиотеки SQLite) sqlite3_column_type().

Обновление: Я уточнил этот вопрос со времени первого ответа от @ mike-sherrill-cat-remind, чтобы прояснить ожидания.

+0

Рассмотрите возможность использования SQLite API, вместо того, чтобы пытаться для анализа вывода оболочки. –

+0

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

ответ

1

В SQLite не всегда имеет смысл эхо-тип данных столбца. SQLite не имеют Типы столбцов данных в традиционном смысле. Вы можете использовать typeof(X) в SQL, чтобы показать «тип данных выражения X».

sqlite> create table test (n integer, d decimal(8, 2)); 
sqlite> insert into test (n, d) values (8, 3.14); 

sqlite> insert into test (n, d) values ('wibble', 'wibble'); 

Вставка текста в целочисленный столбец завершается успешно.

sqlite> select n, typeof(n), d, typeof(d) from test; 
 
    n   typeof(n) d   typeof(d) 
    ---------- ---------- ---------- ---------- 
    8   integer  3.14  real  
    wibble  text  wibble  text  

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

sqlite> select '(' || typeof(n) || ')^_' || n as caret_n from test; 
 
    caret_n     
    ------------------------- 
    (integer)^_8    
    (text)^_wibble   


SQLite Core Functions

+0

Спасибо! Я надеялся найти способ получить это без изменения основных запросов (как вы это делаете для ** \ *** в любом случае?). Я боюсь, что это (удивительный) недостаток в выпуске оболочки SQLite. – rgchris

+0

@rgchris: Я не могу представить ни одного интерфейса командной строки SQL, который печатает данные типа в выводе. Я никогда не использую 'select * from ...' в производстве. –

+0

@ mike-sherrill-cat-remember Интерфейс библиотеки SQLite включает в себя базовую информацию о типе в своем ответе. Другие - за столбец. Учитывая пример в моем вопросе, это может показаться уместной и действительно фундаментальной частью любого ответа. – rgchris

0

Оболочка всегда преобразует распечатаны значения строк. (Это то, что означает «печать».)

Если вы не хотите, чтобы добавить отдельные выходные столбцы для типов, вы можете использовать quote function выводить все значения в соответствии с правилами синтаксиса SQL:

sqlite> with v(x) as (values (null), (1), (2.3), ('hello'), (x'00')) select quote(x) from v; 
NULL 
1 
2.3 
'hello' 
X'00' 
+0

«Оболочка всегда ...» - вы узнаете о [сериализации] (https://en.wikipedia.org/wiki/Serialization), поразительно, сколько информации может быть передано в строках. Как вы используете ** quote() ** в общем смысле, скажем, применительно к результату запроса? – rgchris

+0

Это функция, как length() или typeof(). –

+0

И, следовательно, потребуется изменить инструкцию SQL. Было бы близко, если бы я мог сказать ** С помощью v (x) As (Выбрать * Из 'вещей') Выбрать Цитата (x) Из v; ** или ** С помощью v (x) As (... мой запрос здесь. ..) Выбрать цитату (x) От v; ** Увы, похоже, что это не так. – rgchris

Смежные вопросы