SQL 服务器 - 根据 table 中的记录构造动态 where 子句

SQL Server - Construct a dynamic where clause based on the records inside a table

我有一个名为 dbo.ItemTagTransactions 的 table,看起来像这样:

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

如何根据上述 table 中 ItemTag 列中的值构建动态 WHERE 子句?此table可能有一个或多个记录。

我将使用的查询如下所示:

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

WHERE子句中的字段总是引用TagValue,可以是1个或多个。它基于以分号分隔的字符串,如下所示。 "Filename.xlsx;ABC7798;;Completed"

想要的结果是这样的:

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

P.S。我将在存储过程中使用它

尝试使用动态 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

如果您的输入是用分号分隔的,您可以简单地将这些分号替换为 ', ' 并用 ' 环绕以形成有效的值列表:

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')

如果要执行查询并存储结果以供进一步处理,请创建一个临时文件 table:

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

INSERT INTO #results
EXEC sp_executesql @Query

如果你有一个 returns 和 table 的字符串拆分函数,那就更简单了,你只需使用

SELECT FK_QueueItem_ItemTagTransaction 
  INTO #results -- for further processing
  FROM dbo.ItemTagTransactions 
 WHERE TagValue IN (SELECT Value 
                      FROM dbo.mySplitStringFunction(@sampleInput))

我希望这对你有用。

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

试试这个...

您可以使用 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;

Returns:

+-------+---------------+
| 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;

Second Demo

但使用 table 值参数更安全,因为字符串可能包含 ,.