为什么存储来自 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 变量
- 而不是 set 我 select-ed @sql变量
- quotename 现在包围 @TableName 变量
- 而不是 sp_executesql 的最后一个参数是 @x = @y output 我只是将它替换为 @y 输出
结论
经过几次测试(主要是删除了一些更改),我可以得出结论,该列表中的最后一点是解决问题的关键。
从语句中删除 quotename 后,我仍然设法将结果保存在变量中,并且由于 @param 变量不是必需的,而是个人喜好,也没有实际意义。
我又一次偶然发现了一个 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 变量
- 而不是 set 我 select-ed @sql变量
- quotename 现在包围 @TableName 变量
- 而不是 sp_executesql 的最后一个参数是 @x = @y output 我只是将它替换为 @y 输出
结论
经过几次测试(主要是删除了一些更改),我可以得出结论,该列表中的最后一点是解决问题的关键。
从语句中删除 quotename 后,我仍然设法将结果保存在变量中,并且由于 @param 变量不是必需的,而是个人喜好,也没有实际意义。