0,0
рейтинг
13 декабря 2013 в 20:30

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

SQLite*, SQL*
Сначала результат, а потом разбор полетов. Допустим, вы создали запрос типа 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».


Спасибо за внимание, удачного дня.
Заболотских Сергей @abby
карма
14,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (4)

  • 0
    Интересно, ни когда об этом не задумывался…

    Правда повторить не удалось:
    sqlite> create table Documents (id integer, name text);
    sqlite> insert into Documents (id, name) values (1, "d1");
    sqlite> select d.id, d.name from Documents d;
    1|d1
    sqlite> .mode line
    sqlite> select d.id, d.name from Documents d;
       id = 1
     name = d1
    sqlite> create view DocView1 as select * from Documents;
    sqlite> select d.id, d.name from DocView1 d;
      d.id = 1
    d.name = d1
    


    $ sqlite3 --version
    3.7.15.2 2013-01-09 11:53:05 c0e09560d26f0a6456be9dd3447f5311eb4f238f
    
  • 0
    Я правильно понял, что ваш запрос отличается от запроса psyX только квадратными скобками? Извините за глупый вопрос, но что они тут означают? Никогда их не использовал и никогда не имел проблем с именами колонок (хоть они и не гарантируют).
    • 0
      Да, только квадратными скобками.
      С некоторых пор в «продакшене» всегда использую квадратные скобки. Они позволяют использовать намного больший набор символов в именах колонок, таблиц и т.п., а так же предотвращают возможные конфликты с зарезервированными словами.
      • 0
        понятно, спасибо

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.