Инструкция SQLIte с использованием массива внутри instr () и IN - PullRequest
0 голосов
/ 30 января 2019

У меня проблемы с структурированием оператора sqlite.Я знаком с instr() и IN, но возможно ли использовать их вместе?У меня есть массив из нескольких подстрок, который я хотел бы увидеть, если столбец содержит какой-либо из них.

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

$array = array('-SVA[rev1]', '-KINGS[rev2]', '-TBS[rev3]');

$query2 = $db->query("SELECT * FROM BOT_Downloads WHERE instr( FileName, IN ('$array') ) AND SeriesTitle = 'The Simple Truth' ");

Я знаю, что использование LIKE '% %' вместо instr() было бы другим способом, однако, если бы я комбинировал его с IN

, это тоже было бы у меня над головой.

Ответы [ 2 ]

0 голосов
/ 30 января 2019

Ваша логика должна быть полностью пересмотрена;IN - это оператор SQL, который определяет, равно ли содержимое параметра слева от оператора IN какому-либо из значений, разделенных запятыми в скобках оператора, и не является допустимым параметром для функции INSTR.Вы должны получать ошибки от SQLite при попытке выполнить этот оператор.

Ваш текущий код должен создать запрос SQL, который выглядит следующим образом:

SELECT *
FROM BOT_Downloads
WHERE instr( FileName, IN ('-SVA[rev1],-KINGS[rev2],-TBS[rev3]') )
    AND SeriesTitle = 'The Simple Truth';

Я гарантирую, что это не то, что вам нужно,Вы хотите построить оператор, который будет выглядеть примерно так:

SELECT *
FROM BOT_Downloads
WHERE (
    instr( FileName, '-SVA[rev1]') or
    instr( FileName, '-KINGS[rev2]') or
    instr( FileName, '-TBS[rev3]'))
    AND SeriesTitle = 'The Simple Truth’;

Кроме того, функция массива PHP не собирается заключать элементы массива в одинарные кавычки, поэтому ваш код будет создавать оператор, который выглядит следующим образом:

SELECT *
FROM BOT_Downloads
WHERE instr( FileName, IN ('-SVA[rev1],-KINGS[rev2],-TBS[rev3]'))
AND SeriesTitle = 'The Simple Truth’;

, где вы, вероятно, снимали что-то похожее на это:

SELECT *
FROM BOT_Downloads
WHERE instr( FileName, IN ('-SVA[rev1]','-KINGS[rev2]','-TBS[rev3]'))
AND SeriesTitle = 'The Simple Truth’;

Однако, поскольку предложение IN не является допустимым параметром для функции Instr, то в любом случае неверно,Предложение IN требует, чтобы у каждого строкового литерала были разделители, в противном случае это просто будет оператор равенства, ищущий одну строку, содержащуюся в скобках.Метод массива PHP по умолчанию не включает эти разделители.

Продолжение:

В продолжение моего предыдущего ответа я использовал следующий SQL для создания и заполнения тестовой таблицы:

BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS `BOT_Downloads` (
    `FileName`      TEXT,
    `SeriesTitle`   TEXT,
    `Note`  TEXT
);
INSERT INTO `BOT_Downloads` (FileName,SeriesTitle,Note) VALUES ('File-SVA[rev1].txt','The Simple Truth','matches filename and series title'),
 ('File-KINGS[rev2].txt','The Simple Truth','matches filename and series title'),
 ('File-TBS[rev3].txt','The Simple Truth','matches filename and series title'),
 ('File-WTH[rev1].txt','The Simple Truth','matches series title, doesn’t match filename'),
 ('File-KINGS[rev1].txt','The Simple Truth','matches series title, doesn’t match filename'),
 ('File-SVA[rev1].txt','War and Peace','matches filename, doesn’t match series title'),
 ('File-KINGS[rev2].txt','War and Peace','matches filename, doesn’t match series title'),
 ('File-TBS[rev3].txt','War and Peace','matches filename, doesn’t match series title'),
 ('File-WTH[rev1].txt','War and Peace','No matches'),
 ('File-KINGS[rev1].txt','War and Peace','No matches');
COMMIT;

Затем я запустил следующий запрос:

SELECT *
FROM BOT_Downloads
WHERE (
    instr( FileName, '-SVA[rev1]') or
    instr( FileName, '-KINGS[rev2]') or
    instr( FileName, '-TBS[rev3]'))
   AND SeriesTitle = 'The Simple Truth’;

и получил результаты того типа, который вы запрашиваете:

"File-SVA [rev1] .txt" "Простая истина "" соответствует имени файла и серии "" File-KINGS [rev2] .txt "" Простая истина "" соответствует имени файла и серии "" File-TBS [rev3] .txt "" Простая правда "" соответствуетимя файла и название серии "

Логика, которую вы преследуете, использование PHP для создания массива и последующее расширение его в оператор SQL не будет работать, если элементы массива являются строками, поскольку PHP не будет автоматически добавлять требуемыеразделители строк для элемента массива;Вот почему вы должны вручную включить одиночные отметки в запросе в операторе IN.Это будет работать с целыми числами, но это плохой подход IMO.Поскольку вы не помещаете разделители строк вокруг каждого отдельного строкового элемента, для которого вы тестируете, ядру SQL кажется, что вы ищете все строки, в которых имя файла содержит буквенную строку '-SVA [rev1], - KINGS [rev2], -TBS [rev3] '- это не то, что вы ищете, и именно поэтому вы не получаете результатов, даже если нет синтаксических ошибок.

0 голосов
/ 30 января 2019

Если вы можете объединить элементы массива с этим:

'-SVA[rev1],-KINGS[rev2],-TBS[rev3]'

, тогда:

SELECT * FROM BOT_Downloads 
WHERE 
  ',' || '-SVA[rev1],-KINGS[rev2],-TBS[rev3]' || ',' LIKE  '%,' || FileName || ',%' 
  AND 
  SeriesTitle = 'The Simple Truth'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...