【问题标题】:sp_executesql not setting a variable correctly in a dynamic sql query in SQL Server 2012sp_executesql 未在 SQL Server 2012 的动态 sql 查询中正确设置变量
【发布时间】:2016-03-31 20:15:39
【问题描述】:

在下面的查询中,我尝试使用在 SQL Server 2012 中由 sp_executesql 执行的动态查询来设置 @productsExist 的值。问题是即使表 @tableName 存在并包含记录,动态查询执行后productsExist的值始终为null

问题:为什么即使表存在且有记录,@productsExist 的查询也会返回 null?

DECLARE @productsExist INT;
DECLARE @countQuery NVARCHAR(MAX) = 'IF OBJECT_ID(@tableName, N''U'') IS NOT NULL 
                     begin  select top(1) @productsExist = 1  from ' + @tableName + ' end';

EXECUTE sp_executesql @countQuery, N'@tableName varchar(500),@productsExist INT',
              @tableName = @tableName,
              @productsExist = @productsExist;

select @productsExist as ProductsExist--returns always a NULL value for ProductsExist

【问题讨论】:

    标签: sql-server-2012 dynamic-sql sp-executesql


    【解决方案1】:

    您需要将@productsExist 参数声明为OUTPUT

    [ 输出 |输出]

    表示参数为输出参数

    DECLARE @productsExist INT
            ,@tableName SYSNAME = 'tab';
    
    DECLARE @countQuery NVARCHAR(MAX) = 
    N'IF OBJECT_ID(@tableName, N''U'') IS NOT NULL 
      begin  select top(1) @productsExist = 1  from ' + QUOTENAME(@tableName) + ' end';
    
    EXECUTE dbo.sp_executesql 
            @countQuery,
            N'@tableName SYSNAME ,@productsExist INT OUTPUT',     -- here
            @tableName = @tableName,
            @productsExist = @productsExist OUTPUT;               -- here
    
    SELECT @productsExist as ProductsExist;
    

    SqlFiddleDemo


    如果指定表中没有记录,@productsExist 将返回NULL。如果您想要 1 表示现有记录,0 表示没有记录,请使用:

    DECLARE @countQuery NVARCHAR(MAX) = 
    N'IF OBJECT_ID(@tableName, N''U'') IS NOT NULL 
      BEGIN
        IF EXISTS (SELECT 1 FROM '+ QUOTENAME(@tableName) + ')
           SELECT @productsExist = 1
        ELSE 
           SELECT @productsExist = 0
      END'; 
    

    SqlFiddleDemo2

    结果:

    table not exists          => NULL
    table exists no records   => 0
    table exists >= 1 records => 1
    

    【讨论】:

    • 优秀的答案。谢谢。使用 SYSNAME 而不是 varchar 来代替 @tableName 是更好的选择吗?
    • @Sunil SYSNAME 只是 NVARCHAR(128) 的别名。我使用它是因为它是一个很好的做法,但 varchar 也可以工作(到 128 个字符)。
    • 我发现QUOTENAME 是一个新的但非常有用的东西,因为它在表名周围放置了方括号。在你回答之前我从来没有遇到过这个。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-02
    相关资源
    最近更新 更多