是否可以通过执行另一个变量来逐个变量?
我的代码现在:
DECLARE
@CHOSENID VARCHAR(MAX),
@sql VARCHAR(MAX),
@COLUMNS VARCHAR(MAX)
SET @CHOSENID = '1032, 1132, 332, 1021'
SET @sql = ' select @COLUMNS = COALESCE(@COLUMNS + '' '', '''') + n.PRODUCT + '' BIGINT NOT NULL DEFAULT -1,''
from MYTABLE n where ID IN ('+@CHOSENID+') and TYPE=''X''
SET @COLUMNS = CONCAT(@COLUMNS, ''TIME DATETIME NOT NULL DEFAULT GETDATE() '')'
PRINT @sql
EXEC (@sql)
PRINT @COLUMNS
结果出错:
必须声明标量变量“@COLUMNS”。
当我尝试在@COLUMNS
内部声明@sql
时,可以执行查询,但PRINT @COLUMNS
不会返回任何内容。
ID
中的{p> MYTABLE
是bigint而@CHOSENID
是varchar,所以我不能简单地执行此操作而不添加@sql
答案 0 :(得分:1)
我认为您正在尝试返回一个值。您应该将sp_executesql
与输出参数一起使用。像这样:
DECLARE @CHOSENID VARCHAR(MAX), @sql NVARCHAR(MAX), @COLUMNS VARCHAR(MAX);
SET @CHOSENID = '1032, 1132, 332, 1021';
SET @sql = N'
declare @columns varchar(max);
select @Columns = COALESCE(@COLUMNS + '' '', '''') + n.PRODUCT + '' BIGINT NOT NULL DEFAULT -1,''
from MYTABLE n
where ID IN (' + @CHOSENID+ ') and TYPE = ''X''
';
exec sp_executesql @sql, 'N'@Columns varchar(max) output', @Columns = @Columns output;
print @Columns;
这不会在最终set
中进行最终连接。它旨在说明如何使用sp_executesql
。
答案 1 :(得分:1)
如果我理解你的尝试正确,根本不需要动态SQL:
试试这个
DECLARE @CHOSENID VARCHAR(MAX)='1032, 1132, 332, 1021';
WITH ChosenIDs AS
(
SELECT A.B.value('.','int') AS ChosenID
FROM (SELECT CAST('<x>' + REPLACE(@CHOSENID,', ','</x><x>') + '</x>' AS XML) AS Splitted) AS tbl
CROSS APPLY Splitted.nodes('/x') AS A(B)
)
SELECT STUFF(
(
SELECT ',' + n.PRODUCT + ' BIGINT NOT NULL DEFAULT -1'
FROM MYTABLE n
WHERE ID IN (SELECT ChosenID FROM ChosenIDs)
AND [TYPE]='X'
FOR XML PATH('')
),1,1,'')
CTE会先将您的@CHOSENID
转移到
'<x>1032</x><x>1132</x><x>332</x><x>1021</x>'
通过XML方法.nodes()
,它被拆分并读作int值。因此,CTE将作为派生表返回您的数字。
而不是SELECT @var=@var + ISNULL(Something,'') FROM...
,您最好使用FOR XML PATH()
的技巧来连接值。
由于我不知道你想要达到的目的是什么,所以这是彻夜不眠...希望它有所帮助......