什么。我在声明@err_message,但随后也声明了@err_message

时间:2018-10-09 04:16:23

标签: sql-server tsql

我要声明@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消息

3 个答案:

答案 0 :(得分:4)

首先,由于需要对不同的表执行相同的查询,因此必须诉诸动态SQL的事实自动听起来像是一个不好的数据库设计。
通常,这意味着您为同一实体拥有多个表,并且这些表名包含应包含在列中的一部分。

例如,诸如Payments_2016Payments_2017Payments_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,而是尝试另一种适合您业务的方法。如果没有,我将专注于错误处理,因为当前处理错误的方法将使您将来头疼。想象一下这些表之一已被更改,删除或损坏。您相信您会知道哪个表填充了错误吗? 因此,您可以通过更多错误处理来扩展当前的解决方案,或者为此创建自己的解决方案。