我已经创建了一个存储过程,我计划将表名传递给允许我从控制表中收集URN,并通过将现有的URN(int identity)添加到存储的表中将其分配给传递的表控制表中的值。
这是存储过程:
ALTER PROCEDURE [dbo].[System_IndividualURN_Processing]
@TableName Varchar(100)
AS Begin
DECLARE @iCounter INT,
@NextCustomerURN INT,
@TSQL Varchar(Max)
SET @TSQL = '
SET '+@iCounter+' = COUNT(*)
FROM dbo.' +@TableName+'
'
EXEC @TSQL
PRINT @iCounter
SELECT @NextCustomerURN = URN --select URN
FROM dbo.System_NextNumbers A
where [Type] = 'NextCustomerURN'
UPDATE A
SET URN = URN + @iCounter
FROM dbo.System_NextNumbers A
where [Type] = 'NextCustomerURN'
SET @TSQL = '
UPDATE A
SET IndividualURN = URN + CONVERT(INT, @NextCustomerURN)-1
FROM dbo.'+@TableName+' A
'
EXEC @TSQL
End
执行时我收到以下错误:
Msg 245,Level 16,State 1,Procedure dbo.System_IndividualURN_Processing,Line 12 [Batch Start line 2] 转换varchar值时转换失败 SET'到数据类型int。
我已将其缩小到以下声明:
SET @TSQL = '
SET '+@iCounter+' = COUNT(*)
FROM dbo.' +@TableName+'
'
建议不可能以这种方式使用动态SQL设置变量,或者语法中缺少某些内容。
非常感谢任何帮助。
答案 0 :(得分:0)
您无法访问在当前批次之外声明的变量(除非它作为参数传递)。因此,尝试在@iCounter
内设置EXEC
将始终失败。
您可以切换到临时表,可以在EXEC
内访问该表。只需确保在外面创建它,否则您将无法在EXEC
之外选择结果。
DECLARE @iCounter INT
DECLARE @TSQL Varchar(Max)
IF OBJECT_ID('tempdb..#CountTotals') IS NOT NULL
DROP TABLE #CountTotals
CREATE TABLE #CountTotals (
TableName VARCHAR(100),
TotalRows INT)
SET @TSQL = '
INSERT INTO #CountTotals (
TableName,
TotalRows)
SELECT
TableName = ''' + @TableName + ''',
TotalRows = COUNT(1)
FROM
dbo.' + @TableName
EXEC (@TSQL)
SET @iCounter = (SELECT C.TotalRows FROM #CountTotals AS C WHERE C.TableName = @TableName)
当您尝试在其他动态SQL上使用@NextCustomerURN
时,会发生同样的事情。您必须将@NextCustomerURN
值呈现为字符串才能正确使用它。
SET @TSQL = '
UPDATE A
SET IndividualURN = URN + CONVERT(INT, ''' + CONVERT(VARCHAR(200), @NextCustomerURN) + ''')-1
FROM dbo.'+@TableName+' A
'
EXEC @TSQL
答案 1 :(得分:0)
您需要使用sys.sp_executesql
您可以参数。 @TSQL
参数需要NVARCHAR
数据类型
这是与你想要的相似的例子。
DECLARE @tableName NVARCHAR(50) = 'Test';
DECLARE @iCounter INT,
@TSQL NVarchar(Max);
CREATE TABLE dbo.Test(Id INT);
INSERT INTO dbo.Test(Id) VALUES(1);
SET @TSQL =
N'
SET @iCounter = (SELECT COUNT(*) FROM dbo.'+@tableName +' )
'
--PRINT @TSQL;
--you pass the @iCounter as an OUTPUT parameter
EXEC sys.sp_executesql @TSQL, N'@iCounter INT OUTPUT', @iCounter OUTPUT
SELECT @iCounter