Pull to refresh

Когда имя колонки в результате запроса в SQLite3 не определено

Reading time2 min
Views5.6K
Сначала результат, а потом разбор полетов. Допустим, вы создали запрос типа select [document].[id], [document].[name] from [SomeDocuments][document], но вместо ожидаемого
  id = 1
 name = d1
получаете
 document = 1
 document = d1

А теперь, если интересно будем разбираться.

В общем все описано в документации к функциям sqlite3_column_name и sqlite3_column_name16
Если вы не используете “as”, то никто не гаранитирует, что вы получите соответствующее имя колонки.
The name of a result column is the value of the «AS» clause for that column, if there is an AS clause. If there is no AS clause then the name of the column is unspecified and may change from one release of SQLite to the next.

Как получить результат в коммандной строке (под рукой была версия 3.7.16.2, в продукте 3.8.1)
.mode line
create table [Documents]([id] integer, [name] text);
insert into [Documents]([id], [name]) values (1, "d1");
select [d].[id], [d].[name] from [Documents][d];
   id = 1
 name = d1
Работает, как и ожидалось. Продолжим
create view [DocView1] as select * from [Documents];
select [d].[id], [d].[name] from [DocView1][d];
А теперь
     d = 1
     d = d1
Результат, приведенный psyX в комментариях (на моих версиях повторяется)
select d.id, d.name from DocView1 d;
  d.id = 1
d.name = d1
Естественно ожидать такое же поведение в последних версиях от функций sqlite3_column_name.

Лирическое отступление
На предыдущей работе я написал очередной ORM-велосипед, который работает с sqlite3 и c mysql. Конечно я столкнулся с этой проблемой, но не придал ей внимания, потому что там использовались алиасы для всех колонок. А теперь решил, что это стоит статьи. Алиасы в той библиотеке понадобились практически сразу, в связи с отсутствием в sqlite3 возможности понять из какой таблицы этот результат и, соответственно в какой объект его сохранять, в случае запросов с join’ами. Вообще неопределенность в связывании колонок результата и реальных таблиц немного беспокоила, но глубже так и не копал, все же работало.
И вот на новой работе, где довольно много хардкодится в плане работы с БД, всплыла такая особенность sqlite3. Возможно это описано в каких-то книгах и давно и хорошо известный факт, но для моих коллег и в очередной раз для меня это было довольно неожиданным открытием.
Дополнение для Qt программистов
Поскольку сейчас программирую с использованием Qt, то хочу поделиться кусочком опыта и тут. Qt настолько “кьют”, что если в имени колонки результата запроса есть точка, то Qt, без всякого предупреждения и возможности это настроить, удаляет все до точки включительно. Т.е. если у вас запрос типа select [document].[id] as [document.id] ..., то на выходе в QSqlRecord у вас будут поля без «document.», т.е. просто «id».


Спасибо за внимание, удачного дня.
Tags:
Hubs:
+3
Comments4

Articles

Change theme settings