#sql #sql-server #tsql
#sql #sql-сервер #tsql
Вопрос:
Я пишу SQL-скрипт, который мы хотим, чтобы наша бухгалтерская команда могла редактировать, не занимаясь проектированием.
Общая идея заключается в том, чтобы иметь скрипт .sql, который определяет некоторые переменные в верхней части запроса, а затем имеет несколько сложных запросов под ним, которые используют эти переменные.
Проблема, с которой мы сталкиваемся, заключается в том, что мы хотим, чтобы команда учета могла указать используемый фильтр. Например:
DECLARE @year INT
DECLARE @month INT
DECLARE @filter VARCHAR(30);
SET @year = 2010
SET @month = 7
SET @filter = '%test%'
Здесь команда может изменить месяц и год, которые возвращают последующие запросы. В этом примере они также могут определить ОДИН элемент фильтра, исключая любые записи, в которых имя пользователя содержит строку 'test'
.
Мой вопрос заключается в том, существует ли способ указать OR для LIKE()
. Например, в идеале мы должны иметь @filter
переменную в виде чего-то вроде '%test%
, или %other%
. Теперь я знаю, что это ненастоящий синтаксис, но мне интересно, есть ли синтаксис, который позволяет мне достичь этого. Я нахмурился MSDN на LIKE()
синтаксис без радости. Должен ли я использовать какое-то другое выражение запроса?
Комментарии:
1. Для этого вы могли бы использовать CLR и регулярные выражения. В синтаксисе шаблона Like нет
|
оператора. Или вы могли бы передавать различные литералы в TVP (предполагая SQL Server 2008) и присоединяться к ним с помощьюLIKE
.
Ответ №1:
Вероятно, проще всего было бы просто использовать несколько параметров, хотя это и не очень красиво:
SET @filter_1 = '%test%'
SET @filter_2 = '%foo%'
SET @filter_3 = '%'
SET @filter_4 = '%'
SELECT *
FROM BAR
WHERE var LIKE @filter_1
OR var LIKE @filter_2
OR var LIKE @filter_3
OR var LIKE @filter_4
OR var LIKE @filter_5
Если по умолчанию они равны%, они всегда будут совпадать по умолчанию.
Вы также могли бы использовать динамический SQL и локальную табличную переменную. По сути, создайте локальную таблицу с одним столбцом, разрешите им изменять инструкции INSERT в этой таблице, затем определите цикл, который перебирает содержимое этой таблицы для динамической генерации предложений LIKE. Это сработало бы, но потребовало бы немного больше кода. Приведенный выше пример быстрый и грязный, но я бы предположил, что этого, вероятно, достаточно для того, что вам нужно сделать.
Комментарии:
1. спасибо, я продолжаю с этим. Как вы говорите, это некрасиво, но он выполняет свою работу.
Ответ №2:
Я бы использовал соединение с LIKE
предикатом. Вы можете выполнить следующий пример кода в окне запроса, чтобы увидеть, как это работает:
DECLARE @tblFilter TABLE
(sFilter nvarchar(MAX) NOT NULL);
INSERT @tblFilter
SELECT * FROM (VALUES ('%one%'), ('%two%'), ('%three%')) v(s);
DECLARE @tblData TABLE
(iId int NOT NULL PRIMARY KEY IDENTITY,
sData nvarchar(MAX));
INSERT @tblData(sData)
SELECT * FROM (VALUES ('one'), ('two three'), ('four')) v(s);
SELECT DISTINCT iId
FROM @tblData d
JOIN @tblFilter f ON d.sData LIKE f.sFilter;
Я предполагаю, что разные строки запроса находятся в @tblFilter
таблице, которая может быть TVP, исходящей из значений XML, из значений, разделенных запятыми, из временной таблицы или чего-то еще.