SQL Server - построение динамического предложения where на основе записей в таблице - PullRequest
0 голосов
/ 04 апреля 2019

У меня есть таблица с именем dbo.ItemTagTransactions, которая выглядит следующим образом:

PK_ID | ItemTag
1     | Filename.xlsx
2     | ABC7798
3     | {empty string}
4     | Completed

Как построить динамическое предложение WHERE на основе значений в столбце ItemTag внутри таблицы выше? Эта таблица может содержать одну или несколько записей.

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

SELECT FK_QueueItem_ItemTagTransaction 
FROM dbo.ItemTagTransactions 
WHERE TagValue = {insert dynamic where clause here}

И поле в предложении WHERE всегда ссылается на TagValue, и оно может быть 1 или больше. Он основан на строке, которая разделена точкой с запятой, как это. "Filename.xlsx; ABC7798 ;; завершено"

Желаемый результат таков:

SELECT FK_QueueItem_ItemTagTransaction 
FROM dbo.ItemTagTransactions 
WHERE TagValue = 'Filename.xlsx' 
   OR TagValue = 'ABC7798' 
   OR TagValue = '' 
   OR TagValue = 'Completed'

P.S. Я буду использовать это внутри хранимой процедуры

Ответы [ 4 ]

1 голос
/ 04 апреля 2019

Если ваш ввод разделен точкой с запятой, вы можете просто заменить эти точки с запятой на ', ' и обернуть их ', чтобы сформировать действительный список значений:

DECLARE @sampleInput NVARCHAR(MAX) = 'Filename.xlsx;ABC7798;;Completed'

DECLARE @Query NVARCHAR(MAX)

SET @Query = 'SELECT FK_QueueItem_ItemTagTransaction FROM dbo.ItemTagTransactions WHERE TagValue IN (' 
           + CONCAT('N''', REPLACE(@sampleInput, ';', ''',N'''), '''')
           + ')'

PRINT @Query

Будет выведено:

SELECT FK_QueueItem_ItemTagTransaction FROM dbo.ItemTagTransactions WHERE TagValue IN (N'Filename.xlsx',N'ABC7798',N'',N'Completed')

Если вы хотите выполнить запрос и сохранить результаты для дальнейшей обработки, создайте временную таблицу:

CREATE TABLE #results
(
    FK_QueueItem_ItemTagTransaction INT -- adjust the
);

INSERT INTO #results
EXEC sp_executesql @Query

Если у вас есть функция разделения строк, которая возвращает таблицу, то это еще проще, вы просто идете с

SELECT FK_QueueItem_ItemTagTransaction 
  INTO #results -- for further processing
  FROM dbo.ItemTagTransactions 
 WHERE TagValue IN (SELECT Value 
                      FROM dbo.mySplitStringFunction(@sampleInput))
0 голосов
/ 04 апреля 2019

Вы можете использовать table-valued parameter как

CREATE TYPE MyType AS TABLE (AValues VARCHAR(50));

CREATE PROCEDURE MyProc
  @AVariable MyType READONLY
AS
  SELECT *
  FROM T
  WHERE ItemTag IN (SELECT AValues FROM @AVariable);

CREATE TABLE T(
  PK_ID INT,
  ItemTag VARCHAR(50)
);

INSERT INTO T VALUES
(1, 'Filename.xlsx'),
(2, 'ABC7798'),
(3, '{empty string}'),
(4, 'Completed');

DECLARE @Var MyType;

INSERT INTO @Var VALUES
('Filename.xlsx'), ('Completed');

EXEC dbo.MyProc @Var;

Возвращает:

+-------+---------------+
| PK_ID |    ItemTag    |
+-------+---------------+
|     1 | Filename.xlsx |
|     4 | Completed     |
+-------+---------------+

Посмотрите, как это работает на этом Live Demo

Вы можете передать строку, и просто

CREATE PROCEDURE MyProc
  @AVariable VARCHAR(300)
AS
  SELECT *
  FROM T CROSS APPLY 
       (SELECT Value FROM STRING_SPLIT(@AVariable, ',')) TT --You can use semi-colon ; instead of ,
  WHERE T.ItemTag = TT.Value;

Второе демо

но более безопасно использовать табличный параметр, так как строка может содержать ,.

0 голосов
/ 04 апреля 2019

Я надеюсь, что это сработает для вас.

SELECT FK_QueueItem_ItemTagTransaction 
FROM dbo.ItemTagTransactions 
WHERE TagValue IN (SELECT ItemTag FROM dbo.ItemTagTransactions)

Попробуйте это ...

0 голосов
/ 04 апреля 2019

Попробуйте использовать Dynamic Sql.Несколько значений тегов должны быть разделены кавычками, такими как InputString, как показано ниже.

  declare @dynamicsql nvarchar(max),@inputstring nvarchar(max)='''ABC101170'',''dfg101264'''
    select @dynamicsql='select * from table 
    where tagvalue in('+@inputstring+')'
print @dynamicsql
exec sp_executesql @dynamicsql
...