【问题标题】:Why does EXEC retport an error of MUST DECLARE SCALAR VARIABLE为什么 EXEC 会报告必须声明标量变量的错误
【发布时间】:2013-02-23 12:03:34
【问题描述】:

我一直在为下面的脚本而苦苦挣扎,我想不出更好的方法。
有没有人看到问题?我正确地声明了变量。为什么会失败?谢谢你的帮助!

DECLARE @var1 as VarChar(50) 
DECLARE @var2 as VarChar(50) 

SET @Var1 = '1, 2, 3, 4, 5'

EXEC('IF (select count(*) from Table1 where Column1 in (' + @Var1 + ')) = 5 
     SET @Var2 = ''True''
ELSE 
     SET @Var2 = ''False''')

SELECT @Var2

错误信息:

必须声明标量变量@Var2

【问题讨论】:

标签: sql sql-server tsql


【解决方案1】:

由于 exec 正在执行单引号内的 SQL 的动态部分。但是@var2 在 exec 之外声明。要解决此问题,请在 exec 中声明并选择 @var2 或使用 @var2 作为 set '+@var2+'

【讨论】:

    【解决方案2】:

    远离执行 sql 字符串的原因有很多。我会将其改写为:

    declare @cnt int
    
    select @cnt = count(1) 
    from Table1 
    where Column1 in
        (select items
        from dbo.Split(@Var1,',')
        )
    
    return @cnt   -- then the calling function says if this is true or false.
    

    拆分功能见:HERE

    【讨论】:

      【解决方案3】:

      如果你想从参数中获取值,你需要使用sp_executesql

      要缩短查询,请使用CASE

      DECLARE @var1 as VarChar(50) 
      DECLARE @var2 as VarChar(50) 
      SET @Var1 = '1, 2, 3, 4, 5'
      SET @sqlCommand = 'SELECT @Var = CASE WHEN count(*) = 5 THEN ''TRUE'' ELSE ''FALSE'' END FROM Table1 where Column1 IN (' + @Var1 + ')'
      EXECUTE sp_executesql @sqlCommand, N'@Var VARCHAR(5) OUTPUT', @Var=@var2 OUTPUT
      SELECT @Var2
      

      如果您想知道@Var1 中的所有ID 是否都在桌子上,您还需要使用DISTINCT

      SET @sqlCommand = 'SELECT @Var = CASE WHEN count(DISTINCT Column1) = 5 THEN ''TRUE'' ELSE ''FALSE'' END FROM Table1 where Column1 IN (' + @Var1 + ')'
      

      【讨论】:

        【解决方案4】:

        那里有两件事..首先“;”在哪里结束句子。您还需要对 varchar 值进行转义。

        同意另一个答案...使用 sp_executeSQL 运行动态 sql。

        一个声明的例子......

        USE AdventureWorks2012;
        GO
        DECLARE @find varchar(30); 
        /* Also allowed: 
        DECLARE @find varchar(30) = 'Man%'; 
        */
        SET @find = 'Man%'; 
        SELECT p.LastName, p.FirstName, ph.PhoneNumber
        FROM Person.Person AS p 
        JOIN Person.PersonPhone AS ph ON p.BusinessEntityID = ph.BusinessEntityID
        WHERE LastName LIKE @find; 
        

        sp_executeSQL 的一个例子..

        DECLARE @IntVariable int;
        DECLARE @SQLString nvarchar(500);
        DECLARE @ParmDefinition nvarchar(500);
        
        /* Build the SQL string one time.*/
        SET @SQLString =
             N'SELECT EmployeeID, NationalIDNumber, Title, ManagerID
               FROM AdventureWorks.HumanResources.Employee 
               WHERE ManagerID = @ManagerID';
        SET @ParmDefinition = N'@ManagerID tinyint';
        /* Execute the string with the first parameter value. */
        SET @IntVariable = 197;
        EXECUTE sp_executesql @SQLString, @ParmDefinition,
                              @ManagerID = @IntVariable;
        /* Execute the same string with the second parameter value. */
        SET @IntVariable = 109;
        EXECUTE sp_executesql @SQLString, @ParmDefinition,
                              @ManagerID = @IntVariable;
        

        【讨论】:

          【解决方案5】:

          使用 sp_executeSQL 代替 exec 并使用输出参数

          例如How to get sp_executesql result into a variable?

          例如

          DECLARE @var1 as VarChar(50) 
          DECLARE @var2 as VarChar(50) 
          DECLARE @ParmDefinition nvarchar(500);
          SET @Var1 = '1, 2, 3, 4, 5'
          
          SET @ParmDefinition = N'@Var2  VarChar(50) OUTPUT';
          
          DECLARE @sSQL nvarchar(500);
          
          set @sSQL =  'IF (select count(*) from Table1 where Column1 in (' + @Var1 + ')) = 5 
               SET @Var2 = ''True''
          ELSE 
               SET @Var2 = ''False'''
          
          EXEC sp_executesql @sSQL, @ParmDefinition, @Var2=@Var2 OUTPUT;
          
          SELECT @Var2;
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-04-08
            • 1970-01-01
            • 2014-08-06
            • 2017-09-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多