我正在尝试使用CONTEXT_INFO
将用户代码从存储过程传递到DELETE触发器以进行表审核。
一切正常,但是我注意到审计表中保存的用户代码的长度不正确。
以此脚本为例......
declare @userCode varchar(50)
set @userCode = 'TestUser'
declare @binary_userCode varbinary(128)
set @binary_userCode = cast(@userCode as varbinary(128))
set CONTEXT_INFO @binary_userCode
declare @temp_userCode varchar(50)
set @temp_userCode = (select cast(CONTEXT_INFO() as varchar(50)))
--set @temp_userCode = rtrim(ltrim(@temp_userCode))
select @userCode, len(@userCode), @temp_userCode, len(@temp_userCode)
set CONTEXT_INFO 0x
结果:
len(@userCode)= 8
len(@temp_userCode)= 50
为什么@temp_userCode
变量的长度为50,如何将其修剪回原始长度以正确存储?
更多信息:
运行SQL Server 2005,但解决方案需要在2005年以后的所有版本中运行。
答案 0 :(得分:7)
当分配给CONTEXT_INFO
时,它会以空字节0x00
填充到128字节,并变为0x5465737455736572000000...
您可以使用
REPLACE(CAST(CONTEXT_INFO() AS varchar(128)) COLLATE Latin1_General_100_BIN ,
0x00,
'')
答案 1 :(得分:3)
用CHAR(0)
填充。尝试:
set @temp_userCode = REPLACE(@temp_userCode COLLATE Latin1_General_BIN, CHAR(0), '');
(编辑:添加了一个明确的COLLATE
条款,但现在我觉得我正在偷马丁。)
答案 2 :(得分:2)
试试这个,它适用于SQL Server 2005:
select cast(substring(CONTEXT_INFO(), 1, charindex(0x00, CONTEXT_INFO())-1) as varchar(128));
不要考虑凌乱的整理: - )
答案 3 :(得分:0)
替换将在SQL服务器unless you specify the collation的不同安装上随机失败:
REPLACE(CAST(CONTEXT_INFO() AS varchar(128)) COLLATE Latin1_General_100_BIN , 0x00, '')
SQL Server有两种不同的行为,具体取决于它的安装方式:
此行为是在近7年前提交给Microsoft的:
问:尝试更换NUL字符时 使用replace(),这是有效的 value有一个SQL排序规则,但不是 Windows排序规则。
A:这是因为0x0000 是Windows中未定义的字符 排序规则。所有未定义的字符 在比较期间被忽略,排序, 和模式匹配。所以寻找 'a'+ char(0)正在寻找 'a',搜索char(0)是 相当于空字符串。
处理未定义字符的方法 有点混乱,但这是 Windows定义的排序方式, 和SQL Server符合 一般的Windows API。
在SQL排序规则中,没有概念 未定义的字符。每个代码 点被赋予权重,这就是原因 我们没有看到问题。