Я хотел бы взять одно значение аргумента из MSSQL, разделить данные на основе (запятой), поместить их в предложениеwhere и выполнить поиск. Число ,(запятая) является случайным.
Если мне нужно использовать переменную, объявив ее, мне нужно динамически создать переменную в соответствии с количеством (запятых). Есть ли способ сделать это? Запрос созданной мной процедуры выглядит следующим образом. Этот запрос не работает.
@IN_ORDER_NO VARCHAR(100)
DECLARE @SPLIT NVARCHAR(200)
SET @SPLIT = TRIM(CHAR(39)+REPLACE(@IN_ORDER_NO, ',', CHAR(39)+','+CHAR(39))+CHAR(39))
SELECT *
FROM EX_TABLE
WHERE EX_COLUMN IN (@SPLIT)
Пожалуйста, скажите мне, как это сделать.
SELECT TRIM(CHAR(39)+REPLACE('11111111,202408050001', ',', CHAR(39)+','+CHAR(39))+CHAR(39))
Если вы поместите результат отсюда в запрос ниже, вы получите значение, но если вы запустите его как процедуру, результата не будет. Может ли это быть проблема с одинарной кавычкой? CHAR(39) — это код (одинарная кавычка)
SELECT *
FROM EX_TABLE
WHERE EX_COLUMN IN (@SPLIT)
Вы отметили здесь множество различных систем БД. В зависимости от того, что вы используете (и его версии), подход к выполнению этого требования может быть разным. Обновите теги, чтобы они наиболее точно отражали продукт (и версию), который вы используете.
Я этого не знал, потому что это был мой первый вопрос. Я отредактировал тег. Спасибо за ваш совет.
К сожалению, модератор алмазов одобрил этот промежуточный пост, не урегулировав такие проблемы.
Дубликат: stackoverflow.com/questions/17481479/…
Этот вопрос похож на: Разобрать строку, разделенную запятыми, чтобы составить IN-список строк в предложении Where. Если вы считаете, что это другое, отредактируйте вопрос, поясните, чем он отличается и/или как ответы на этот вопрос не помогают решить вашу проблему.
Учитывая, что вы используете SQL Server, который не имеет самых широких строковых функций, вы можете пойти на этот LIKE
трюк:
SET @INP = '11111111,202408050001'
SELECT *
FROM EX_TABLE
WHERE ',' + @INP + ',' LIKE '%,' + EX_COLUMN + ',%';
Почему LIKE, а не STRING_SPLIT?
@MatBailie мне больше нравится моя версия :-P
@TimBiegeleisen Почему ты ставишь запятую после того, где?
@mongvely — Дополнительные разделители с обеих сторон выражения LIKE
необходимы, чтобы избежать частичных совпадений строк, таких как совпадение '23'
с '123,789'
.
В опубликованном вами условии WHERE EX_COLUMN IN (@SPLIT)
переменная @SPLIT
представляет собой простую строку, ничем не отличающуюся от любой другой строки. Поскольку это одно значение, выражение эквивалентно WHERE EX_COLUMN = @SPLIT
. Семантика SQL-сервера не предусматривает дальнейшего анализа этой строки в список строк только потому, что на нее ссылается оператор IN (...)
.
Что вы можете сделать, это:
EXEC
.STRING_SPLIT()
, чтобы преобразовать список, разделенный запятыми, в набор значений, на которые можно ссылаться в операции IN (subselect)
или JOIN
.Последний вариант позволяет избежать неэффективности сопоставления с образцом и создает запрос, который является SARGable, то есть может эффективно использовать индексы.
SELECT *
FROM EX_TABLE
WHERE EX_COLUMN IN (SELECT * FROM STRING_SPLIT(@IN_ORDER_NO, ','));
SELECT X.*
FROM STRING_SPLIT(@IN_ORDER_NO, ',') S
JOIN EX_TABLE X
ON X.EX_COLUMN = S.value;
Если EX_COLUMN
является числовым типом или UNIQUEIDENTIFIER
, приоритет типа данных заставит преобразовать строку S.value
в соответствие с этим типом перед выполнением поиска или сравнения. (При желании вы можете добавить явное преобразование, используя CAST()
, CONVERT()
, TRY_CAST()
или TRY_CONVERT()
к ссылке S.value
.
См. эту db<>fiddle для демонстрации различных вариантов.
SQL Server от Microsoft — это не то же самое, что MySQL или Oracle. Зачем все теги? Пожалуйста, выберите только тот, который вы действительно используете.