我想动态调用存储过程,因为我的程序名称存储在某个地方,我还需要将该过程的结果存储到表变量中。因此我必须编写以下sql代码,
在以下代码中 @tblEmailIds是我要存储SP结果的表变量 @tempEmailSource是过程的名称 @tempRecipientsIdsCSV是我的SP接受的第一个参数 @ObjectMasterId是SP接受的第二个参数(可选)
DECLARE @tempTypeName NVARCHAR(100),
@tempTypeId INT,
@tempEmailSource NVARCHAR(100),
@tempRecipientsIdsCSV NVARCHAR(MAX),
@tempIsObjectSpecific BIT,
@sqlQuery NVARCHAR(MAX) = 'INSERT INTO @tblEmailIds '
SELECT TOP 1 @tempTypeName = NAME,
@tempTypeId = Id,
@tempEmailSource = EmailListSourceName
FROM @tbleRecipientsTypes WHERE IsEmailIdsFetched = 0
SELECT @tempRecipientsIdsCSV = SUBSTRING(
(SELECT ',' + CAST(RT.EmailRecipientId AS NVARCHAR(50))
FROM @tbleRecipientsTypes RT WHERE RT.Id = @tempTypeId
ORDER BY RT.EmailRecipientId
FOR XML PATH('')),2,200000)
SELECT @tempRecipientsIdsCSV
SET @sqlQuery = @sqlQuery + 'EXEC ' + @tempEmailSource +' ' +'''' + @tempRecipientsIdsCSV +''''
IF (@tempIsObjectSpecific = 1)
BEGIN
SET @sqlQuery = @sqlQuery + ' ' + @ObjectMasterId
END
PRINT @SQLQUERY
EXECUTE SP_EXECUTESQL
@SqlQuery,'@IdsCSV NVARCHAR(MAX) OUTPUT,
@ObjectMasterId INT = NULL OUTPUT', @tblEmailIds
我收到以下错误
消息214,级别16,状态3,过程sp_executesql,第6行过程 期望参数' @ params'类型&n; ntext / nchar / nvarchar'。
答案 0 :(得分:1)
将前缀N
添加到@params
的{{1}}。
您还需要存储SP_EXECUTESQL
参数
OUTPUT
答案 1 :(得分:1)
这里有很多问题。
正如错误消息明确指出的那样,参数列表需要为NVARCHAR
,因此只需在该字符串文字前加N
(如@ VR46的答案中所述)。
表变量不会像您尝试使用它们那样工作。首先,您不要声明@tblEmailIds
,但即使您这样做,表变量的范围也是本地的,并且它们不能用作OUTPUT
参数。相反,您需要创建一个本地临时表(即#tblEmailIds
)并执行INSERT INTO #tblEmailIds
。
您引用了另一个尚未声明或填充的表变量@tbleRecipientsTypes
。
您确实声明@tempIsObjectSpecific
但从未设置它,因此始终为NULL
。
为什么@IdsCSV
(在sp_executesql
调用参数列表中)声明为OUTPUT
?您不仅没有传递@tempRecipientsIdsCSV
(在动态SQL中为@IdsCSV
),甚至不需要成为参数,因为您直接将@tempRecipientsIdsCSV
的值连接成动态SQL,动态SQL中没有@tempRecipientsIdsCSV
变量开头。因此,请从参数列表中删除@IdsCSV NVARCHAR(MAX) OUTPUT,
。
你说“@tempRecipientsIdsCSV是我的SP接受的第一个参数”,但是你在代码中声明它,这会导致错误。
什么数据类型是@ObjectMasterId
?你说它被传递到proc中,我看到它被连接到动态SQL中,所以它需要是一个字符串类型(即INT
参数列表中显示的不是sp_executesql
)或者它需要在CONVERT(NVARCHAR(10), @ObjectMasterId
。
如果传入@ObjectMasterId
,为什么在OUTPUT
参数列表中将其声明为sp_executesql
?但更好的问题可能是:为什么你甚至将它传递到sp_executesql
,因为你直接将它连接到动态SQL?动态SQL中没有使用@ObjectMasterId
变量。