为什么存储来自 sp_executesql return NULL 的值?

Why does storing a value from sp_executesql return NULL?

我又一次偶然发现了一个 SQL 的错误。以下代码:

create trigger tc_trigger_olt_UPDATE on tick_orderline_type
for update as
declare @UserId varchar(32)     --
declare @ClientId varchar(32)   --
declare @CaseId varchar(32)     --
declare @TableName varchar(64)  --Used
declare @RecordId varchar(512)  --Used
declare @Descr varchar(128)     --
declare @RemoteIP varchar(16)   --Used

select @TableName   = object_name(parent_id) from sys.triggers where object_id = @@procid
select @RemoteIP    = client_net_address from sys.dm_exec_connections where Session_id = @@SPID
if exists(select * from information_schema.columns where table_name = @TableName and column_name = 'id')
begin
    select @RecordId = id from inserted
end

declare @sql nvarchar(max)
set @sql = 'select case_id from '+@TableName+' where id = '''+@RecordId+'''';

exec sp_executesql @sql, N'@out_param varchar(32) OUTPUT', @out_param=@CaseId OUTPUT

execute update_tick_orderline_type @UserId, @ClientId, @CaseId, @TableName, @RecordId, @Descr, @RemoteIP

用于SSMS中的填写和审计-table,有效。它存储 table 被编辑的 table、记录、日期和 IP 地址。

我目前正在尝试获取哪个客户的数据,对于哪种情况,已使用从上面截取的以下内容进行了编辑:

declare @sql nvarchar(max)
set @sql = 'select case_id from '+@TableName+' where id = '''+@RecordId+'''';

exec sp_executesql @sql, N'@out_param varchar(32) OUTPUT', @out_param=@CaseId OUTPUT

在我的结果 window(显示 select 语句结果的那个)中,我可以看到 @sql 语句有select编辑了正确的 case_id;但是,将其存储在 @CaseId 变量中,returns NULL。一旦我有了 @CaseId,我就可以得到 @ClientId,所以我在这里被难住了。

为什么语句输出正确的case_id,却存储为NULL?

一点旁注:case_id 仅在存在 exec 语句时输出, 否则不是

我设法解决了自己的困境,通过将之前的 'select x from @TableName' 块更改为:

declare @sql nvarchar(max)
declare @params nvarchar(max)
set @params = N'@iCaseId varchar(max) output'
select @sql = N'select @iCaseId = case_id from '+quotename(@TableName)+
        ' where id = '''+@RecordId+''''

execute sp_executesql @sql, @params, @CaseId output

有什么变化?

  • 为了可读性,我声明了一个额外的@params 变量
  • 而不是 setselect-ed @sql变量
  • quotename 现在包围 @TableName 变量
  • 而不是 sp_executesql 的最后一个参数是 @x = @y output 我只是将它替换为 @y 输出

结论

经过几次测试(主要是删除了一些更改),我可以得出结论,该列表中的最后一点是解决问题的关键。
从语句中删除 quotename 后,我仍然设法将结果保存在变量中,并且由于 @param 变量不是必需的,而是个人喜好,也没有实际意义。