SQL Server-根据表内的记录构造一个动态where子句

时间:2019-04-04 06:51:09

标签: sql sql-server tsql select where

我有一个名为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 个答案:

答案 0 :(得分:1)

如果您的输入是用分号分隔的,则只需用', '替换那些分号,然后用'将其括起来即可形成有效的值列表:

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

我希望这对您有用。

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

尝试一下...

答案 3 :(得分:0)

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

Second Demo

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