我使用Excel连接连接到SQL Server以查询从SQL服务器到Excel的数据。
我在Excel连接中有几次WHERE子句。我需要不时替换WHERE多值列表。要简单地替换,我想使用本地参数@Trans。使用local参数,我只能更改它,所有SQL都将使用它来查询。
WHERE Type in ('R','D','C')
如果是单一选项,则代码可以正常工作。
DECLARE @TRans CHAR(200)= 'R';
SELECT .....
WHERE Type in (@Trans)
如果是多个选项,则以下代码无效
DECLARE @TRans CHAR(200)= 'R,D,C';
SELECT .....
WHERE Type in (@Trans)
DECLARE @TRans CHAR(200)= '''R'''+','+'''D'''+','+'''C''';
SELECT .....
WHERE Type in (@Trans)
如何为多个值列表声明@Trans,例如(' R',' D',' C')?谢谢。
答案 0 :(得分:2)
您可以使用动态sql
DECLARE @TRans VARCHAR(200)= '''R'',''D'',''C''';
DECLARE @sql VARCHAR(MAX) = '';
SET @sql = 'SELECT * FROM table WHERE Type in (' + @Trans + ');'
EXEC @sql
记下@TRans中这些字符值后的值的引号。
如果要检查@sql的值,您将看到构造的sql语句,请用PRINT @sql替换EXEC @sql。
@sql的结果
SELECT * FROM table WHERE Type in ('R','D','C');
答案 1 :(得分:1)
正如您现在所看到的,SQL Server不支持宏替代。这留下了几个选择。一种是拆分字符串。
如果不是2016年,这里是一种快速的在线方法,不需要表格值函数
示例强>
Declare @Trans varchar(max)='R,D,C' -- Notice no single quotes
Select ...
Where Type in (
Select RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
From (Select x = Cast('<x>' + replace(@Trans,',','</x><x>')+'</x>' as xml).query('.')) as A
Cross Apply x.nodes('x') AS B(i)
)
答案 2 :(得分:0)
您可以创建一个名为LocalParameter
的表,并在那里保留局部变量。您只能通过更新LocalParameter
表而不更改queries
来获取数据。
CREATE TABLE LocalParameter (Trans VARCHAR(MAX))
INSERT INTO LocalParameter
VALUES
(
',R,'
)
使用LIKE
,您可以像这样使用它:
SELECT .....
WHERE (SELECT TOP 1 A.Trans FROM LocalParameter A) LIKE ',' + Type + ','
要更改WHERE
子句:
UPDATE LocalParameter
SET Trans = ',R,D,C,'
查询:
SELECT .....
WHERE (SELECT TOP 1 A.Trans FROM LocalParameter A) LIKE ',' + Type + ','
将局部变量添加到逗号的开头和结尾。
答案 3 :(得分:0)
您可以使用拆分方法拆分csv值,如下所示
DECLARE @delimiter VARCHAR(10)=','
DECLARE @input_string VARCHAR(200)='R,D,C'
;WITH CTE AS
(
SELECT
SUBSTRING(@input_string,0,CHARINDEX(@delimiter,@input_string)) AS ExtractedString,
SUBSTRING(@input_string,CHARINDEX(@delimiter,@input_string) + 1,LEN(@input_string)) AS PartString
WHERE CHARINDEX(@delimiter,@input_string)>0
UNION ALL
SELECT
SUBSTRING(PartString,0,CHARINDEX(@delimiter,PartString)) AS ExtractedString,
SUBSTRING(PartString,CHARINDEX(@delimiter,PartString)+1,LEN(PartString)) AS PartString
FROM CTE WHERE CHARINDEX(@delimiter,PartString)>0
)
SELECT ExtractedString FROM CTE
UNION ALL
SELECT
CASE WHEN CHARINDEX(@delimiter,REVERSE(@input_string))>0
THEN REVERSE(SUBSTRING(REVERSE(@input_string),0,CHARINDEX(@delimiter,REVERSE(@input_string))))
ELSE @input_string END
OPTION (MAXRECURSION 0)
这种拆分方法没有任何循环,所以它会很快。然后将其与您的查询集成,如下所述
DECLARE @delimiter VARCHAR(10)=','
DECLARE @input_string VARCHAR(200)='R,D,C'
;WITH CTE AS
(
SELECT
SUBSTRING(@input_string,0,CHARINDEX(@delimiter,@input_string)) AS ExtractedString,
SUBSTRING(@input_string,CHARINDEX(@delimiter,@input_string) + 1,LEN(@input_string)) AS PartString
WHERE CHARINDEX(@delimiter,@input_string)>0
UNION ALL
SELECT
SUBSTRING(PartString,0,CHARINDEX(@delimiter,PartString)) AS ExtractedString,
SUBSTRING(PartString,CHARINDEX(@delimiter,PartString)+1,LEN(PartString)) AS PartString
FROM CTE WHERE CHARINDEX(@delimiter,PartString)>0
)
SELECT * FROM [YourTableName] WHERE Type IN
(SELECT ExtractedString FROM CTE
UNION ALL
SELECT
CASE WHEN CHARINDEX(@delimiter,REVERSE(@input_string))>0
THEN REVERSE(SUBSTRING(REVERSE(@input_string),0,CHARINDEX(@delimiter,REVERSE(@input_string))))
ELSE @input_string END
)OPTION (MAXRECURSION 0)
答案 4 :(得分:0)
如果可能的话,添加一个新表,然后在所有查询中加入它:
CREATE TABLE SelectedType
(
[Type] CHAR(1) PRIMARY KEY
)
INSERT INTO SelectedType
VALUES ('R','D','C')
然后您的查询变为:
SELECT *
FROM MyTable MT
INNER JOIN SelectedType [ST]
ON ST.[Type] = MT.[Type]
如果您需要添加,更新或删除类型,请更新SelectedType表中的行。
这样可以使用基于SET的查询,易于理解,易于添加,更新或删除所需类型。