Sqlite: условно запросите две таблицы, одна из которых не будет существовать

#sqlite

Вопрос:

Я уверен, что смогу решить эту проблему программно, но мне любопытно, смогу ли я сделать это за один запрос.

Контекст:

Я буду запрашивать несколько баз данных, в некоторых будет таблица; «таблица», в других вместо нее будет таблица; «table_v2». Я хочу запустить ту же инструкцию SELECT в существующей таблице. Я знаю, что могу проверить, существует ли таблица, но я хочу знать, могу ли я сделать все это в одном заявлении.

краткое описание кода psuedo того, что я хочу сделать, в одном заявлении:

 if 'SELECT name FROM sqlite_master WHERE type='table' AND name=''table'; is not empty:
     SELECT * FROM table;
else 
     SELECT * FROM table_v2;
 

Я обязан ограничениям, выходящим из-под моего контроля.

Мысли:

  1. Могу ли я сделать так, чтобы имя таблицы было регулярным выражением?
  2. Могу ли я запустить оба ВЫБОРА, проигнорировать неудачный результат и просто вернуть успех?

Комментарии:

1. Можете ли вы создать таблицу имен представлений во второй базе данных, которая возвращает данные из table_v2 ?

Ответ №1:

Как правило, вы не можете сделать ни того, ни другого. Планировщик запросов в SQLite должен заранее знать имя таблицы, и оно должно быть допустимым, чтобы он мог определить, какие пути выбрать.

Вы можете использовать загружаемое расширение eval для создания SQL-запроса на основе схемы. Тем не менее, это создает вариант той же проблемы, поскольку планировщику запросов требуется имя таблицы, вам необходимо создать всю инструкцию SQL, а затем запустить ее, поэтому вам потребуется два eval вызова.

 SELECT EVAL(
    'SELECT * FROM ''' || 
    EVAL('SELECT name FROM sqlite_master WHERE type=''table'' AND name IN (''table'', ''table_v2'');') || 
    ''';'
);
 

Чтобы использовать эту eval функцию, вам нужно либо создать и загрузить расширение в виде библиотеки, либо встроить его в собственную пользовательскую сборку самого SQLite.

Конечно, я не могу ответить, следует ли вам это делать.