【问题标题】:EXEC sp_executesql doesn't work or doesn't return dataEXEC sp_executesql 不起作用或不返回数据
【发布时间】:2017-11-30 20:06:44
【问题描述】:

我有来自触发器的代码部分。当我测试我的触发器时,我的 exec 没有返回任何数据。

我将我的 exec 值声明为:

declare
    @sql nvarchar(MAX), 
    @SQLString varchar(MAX)

这里是选择:

set @sql =  N'select ' 
        set @sql = @sql +   '@SQLString = convert(varchar(1000),d.' + @fieldname + ')' +' + convert(varchar(1000),i.' + @fieldname + ')'
set @sql = @sql +   ' from #ins i full outer join #del d'
set @sql = @sql +   @PKCols --
set @sql = @sql +   ' where i.' + @fieldname + ' <> d.' + @fieldname 
set @sql = @sql +   ' or (i.' + @fieldname + ' is null and  d.' + @fieldname + ' is not null)' 
set @sql = @sql +   ' or (i.' + @fieldname + ' is not null and  d.' + @fieldname + ' is null)' 

(所有变量都可以正常工作):就像我打印 @sql 一样 ->

select @SQLString = convert(varchar(1000), d.ActionID) + convert(varchar(1000), i.ActionID) 
from #ins i 
full outer join #del d on i.ActionID = d.ActionID 
where i.ActionID <> d.ActionID 
   or (i.ActionID is null and d.ActionID is not null) 
   or (i.ActionID is not null and d.ActionID is null)

这里是执行:

EXEC sp_executesql @sql, 
        N'@SQLString varchar(MAX) OUTPUT', 
        @SQLString = @SQLString OUTPUT;

但 print 什么也没显示:

print '@SQLString:' + @SQLString;

【问题讨论】:

    标签: sql-server exec sp-executesql


    【解决方案1】:

    调查您的 select 语句,通过在一些测试数据上运行此语句,没有返回 #ins 和 #del 中的 ActionID 均非空的情况,其中一个对我来说始终为空。

    这会导致您添加一个非空字符串和一个空字符串,即

    convert(varchar(1000), d.ActionID) + convert(varchar(1000), i.ActionID)
    

    然后返回一个 null 并且@SQLString 结果为 null。

    我拼凑的一些测试代码:

    CREATE TABLE #ins 
    (
        ActionID INT
    )
    
    CREATE TABLE #del
    (
        ActionID INT
    )
    
    INSERT INTO #ins
    VALUES (1),(3),(5),(7),(9)
    
    --Data sets mostly disjoint, have 1 overlapping value to see what happens.
    INSERT INTO #del
    VALUES (2),(4),(6),(8),(9),(10)
    
    --Visual demo of return values.
    SELECT * 
    FROM #ins i 
         FULL OUTER JOIN #del d ON i.ActionID = d.ActionID 
    WHERE i.ActionID != d.ActionID 
          OR (i.ActionID IS NULL AND d.ActionID IS NOT NULL) 
          OR (i.ActionID IS NOT NULL AND d.ActionID IS NULL)
    
    --Original SQL to demonstrate NULL return value.
    DECLARE @sql NVARCHAR(MAX) = 'SELECT @SQLString = CONVERT(NVARCHAR(1000), d.ActionID) + CONVERT(NVARCHAR(1000), i.ActionID) FROM #ins i FULL OUTER JOIN #del d ON i.ActionID = d.ActionID WHERE i.ActionID != d.ActionID OR (i.ActionID IS NULL AND d.ActionID IS NOT NULL) OR (i.ActionID IS NOT NULL AND d.ActionID IS NULL)'
           ,@SQLString NVARCHAR(MAX)
    
    EXEC sp_executesql @sql, N'@SQLString NVARCHAR(MAX) OUTPUT', @SQLString = @SQLString OUTPUT
    
    SELECT @SQLString
    
    --Modified original vars/sql and wrapped in ISNULL to demonstrate non-null return value.
    DECLARE @sql2 NVARCHAR(MAX) = 'SELECT @SQLString = CONVERT(NVARCHAR(1000), ISNULL(d.ActionID,0)) + ''-'' + CONVERT(NVARCHAR(1000), ISNULL(i.ActionID,0)) FROM #ins i FULL OUTER JOIN #del d ON i.ActionID = d.ActionID WHERE i.ActionID != d.ActionID OR (i.ActionID IS NULL AND d.ActionID IS NOT NULL) OR (i.ActionID IS NOT NULL AND d.ActionID IS NULL)'
           ,@SQLString2 NVARCHAR(MAX)
    
    EXEC sp_executesql @sql2, N'@SQLString NVARCHAR(MAX) OUTPUT', @SQLString = @SQLString OUTPUT
    
    SELECT @SQLString
    

    【讨论】:

    • 太棒了!很高兴听到:)
    【解决方案2】:

    使用“+”运算符将 Null 与字符串连接时,您会得到 Null。

    请改用CONCAT 函数。它为您将参数转换为字符串,并将 Null 视为空字符串。

    【讨论】:

    • 我们使用 SQL 2008,我认为 Concat 从 2012 年开始可用。但是感谢您的推荐!
    猜你喜欢
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-16
    • 1970-01-01
    • 2013-01-07
    • 1970-01-01
    相关资源
    最近更新 更多