我要声明@err_message
,然后要像这样声明@err_message
:
ALTER PROCEDURE USP_FONM_16_FILES
(@COMMAND NVARCHAR (MAX),
@DBNAME NVARCHAR(MAX),
@FORMAT_TABLE NVARCHAR (MAX))
AS
BEGIN
IF @COMMAND = N'HOMEOWNER'
BEGIN
DECLARE @ERR_MESSAGE VARCHAR(MAX)=NULL
DECLARE @SQL1 NVARCHAR (MAX)
SET @SQL1 = N''+
CONCAT('IF (SELECT MAX(DATA_TYPE) FROM ', @FORMAT_TABLE ,')=', '''D''','
BEGIN
SELECT TOP 100* FROM ', @FORMAT_TABLE , '
END
ELSE
BEGIN
SET @ERR_MESSAGE= ''NOT AVAILABLE''
RAISERROR(@ERR_MESSAGE, 16, 1)
END'
)
END
运行过程-我收到此错误:
第137条消息,第15级,状态1,第51行
必须声明标量变量“ @ERR_MESSAGE”。第13层状态2,第52行,第137消息
答案 0 :(得分:4)
首先,由于需要对不同的表执行相同的查询,因此必须诉诸动态SQL的事实自动听起来像是一个不好的数据库设计。
通常,这意味着您为同一实体拥有多个表,并且这些表名包含应包含在列中的一部分。
例如,诸如Payments_2016
,Payments_2017
和Payments_2018
之类的表-虽然应该只有一个名为Payments
的表,其列为Payement_Year
。
因此正确的解决方案可能是重构数据库并将这种重复表更改为单个表。
话虽如此,我知道很多人无法更改数据库设计,因此以下是在重构数据库时可以使用的解决方案:
您在存储过程中声明了@ERR_MESSAGE
变量,但是您尝试在动态SQL中使用它-并且该变量在不同的范围内运行,因此无法访问声明的@ERR_MESSAGE
存储过程。
您可以在动态SQL中声明它,或使用正确的参数定义将其传递到sp_ExecuteSql
。
您没有显示如何运行此SQL,因此很难为您提供合适的代码示例。
另外,您有SELECT TOP 100*...
-您需要在100
和*
-SELECT TOP 100 * FROM
之间留一个空格。...
答案 1 :(得分:0)
更新的查询-尝试
ALTER PROCEDURE USP_FONM_16_FILES
(
@COMMAND NVARCHAR (MAX) ,
@DBNAME NVARCHAR(MAX) ,
@FORMAT_TABLE NVARCHAR (MAX)
)
AS
BEGIN
IF @COMMAND =N'HOMEOWNER'
BEGIN
DECLARE @SQL1 NVARCHAR (MAX)
SET @SQL1=N''+
CONCAT('IF (SELECT MAX(DATA_TYPE) FROM ', @FORMAT_TABLE ,')=', '''D''','
BEGIN
SELECT TOP 100 * FROM ', @FORMAT_TABLE , '
END
ELSE
BEGIN
DECLARE @ERR_MESSAGE VARCHAR(MAX)=NULL
SET @ERR_MESSAGE= ''NOT AVAILABLE''
RAISERROR(@ERR_MESSAGE, 16, 1)
END'
)
END
sp_ExecuteSql @SQL1
END
答案 2 :(得分:0)
我完全同意@Zohar Peled。另外,我宁愿不使用动态SQL,而是尝试另一种适合您业务的方法。如果没有,我将专注于错误处理,因为当前处理错误的方法将使您将来头疼。想象一下这些表之一已被更改,删除或损坏。您相信您会知道哪个表填充了错误吗? 因此,您可以通过更多错误处理来扩展当前的解决方案,或者为此创建自己的解决方案。