【发布时间】:2021-11-16 21:43:43
【问题描述】:
使用 SQL Server 2016。我正在编写存储过程。我在WHILE 循环中发生了以下代码
DELCARE @recordExists int;
SET @recordExistsQuery = 'SELECT @recordExists=COUNT(*) FROM @fullTableName WHERE validFrom <= CAST(@asOfDate as datetime)';
exec sp_executesql @recordExistsQuery, N'@recordExists INT OUT, @fullTableName varchar(60), @asOfdate datetime' @recordExists OUT
我得到错误`必须声明表变量@fullTableName但是我已经声明并设置了这个变量(在while循环之前)并在while循环之前多次使用它,所以我知道它存在并且是有效的。它是这样定义的 -
DECLARE @fullTableName varchar(60);
SET @fullTableName = (SELECT CONCAT(@schema, '.', @TableName));
我在 while 循环之前打印了它,它看起来很好,我每个循环都有它打印机,它也可以工作。
我这里的动态 sql 有什么问题?我正在尝试使用参数化方法而不是使用引号构建字符串,因为我正在处理日期时间并且希望通过比一堆引号更好的做法来做到这一点。那可能吗?我该如何重写
SET @recordExistsQuery = 'SELECT @recordExists=COUNT(*) FROM @fullTableName WHERE validFrom <= CAST(@asOfDate as datetime)';
exec sp_executesql @recordExistsQuery, N'@recordExists INT OUT, @fullTableName varchar(60), @asOfdate datetime' @recordExists OUT
让它按预期工作?
更新:硬编码表名而不是将其作为参数传递。我现在从以下代码中收到以下错误 -
SET @recordExistsQuery = 'SELECT @recordExists=COUNT(*) FROM ' + @fullTableName + ' WHERE validFrom<=CAST(@asOfDate as datetime)';
PRINT @recordExistsQuery
exec sp_executesql @recordExistsQuery, N'@asOfDate datetime, @recordExists INT OUT', @recordExistsOut`
打印语句显示
SELECT @recordExists=COUNT(*) FROM [MySchema].[MyTable] WHERE validFrom<=(@asOfDate as datetime)
我现在得到的错误是
Msg 8162, Level 16, State 2, Line 0
The formal parameter "@asOfDate" was not declared as an OUTPUT paramter, but the actual paramter passed in requested output.
我将@asOfDate 作为我的存储过程的参数,定义为
@asOfDate DATETIME=NULL 如果没有传入,我的 sp 的第一行设置一个默认值
IF @asOfdate IS NULL
SET @asOfDate = GETDATE();
有人知道现在出了什么问题吗?
更新 2: 改用这条线
'SELECT @recordExists=COUNT(*) FROM '+ @fullTableName +' WHERE validFrom <= CAST('+@asOfDate'+' as datetime)'
现在得到错误Msg 241, Level 16, State 1, Conversion failed when converting date and/or time from character string.
@asOfDate 被定义为我的 sp 的参数,如 @asOfDate datetime=NULL 并初始化为 getdate()。我正在使用@asOfDate=null 对此进行测试,因此它使用 getdate() 来初始化值。
【问题讨论】:
-
您根本不能使用表名作为参数,您需要预先构建这部分查询字符串。
-
另外,请使用
QUOTENAME:SELECT @fullTableName = CONCAT(QUOTENAME(@schema), '.', QUOTENAME(@TableName))。没有必要因为不寻常的名字而无缘无故地打破。 -
@Arvo 谢谢你,我不知道,我能够通过这些信息克服这个错误。
-
@JeroenMostert 好主意,感谢您提供的信息。不知道 QUOTENAME,对用 SQL 编写逻辑非常陌生。
标签: sql sql-server stored-procedures