我正在尝试使用 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,如何将其修剪回原始长度以正确存储?
更多信息:
分配时 CONTEXT_INFO
它以空字节填充 0x00
长度为128个字节并成为 0x5465737455736572000000...
您可以使用
REPLACE(CAST(CONTEXT_INFO() AS varchar(128)) COLLATE Latin1_General_100_BIN ,
0x00,
'')
分配时 CONTEXT_INFO
它以空字节填充 0x00
长度为128个字节并成为 0x5465737455736572000000...
您可以使用
REPLACE(CAST(CONTEXT_INFO() AS varchar(128)) COLLATE Latin1_General_100_BIN ,
0x00,
'')
它被填补 CHAR(0)
。尝试:
set @temp_userCode = REPLACE(@temp_userCode COLLATE Latin1_General_BIN, CHAR(0), '');
(编辑:添加了一个明确的 COLLATE
条款,虽然现在我觉得我在偷马丁。)
试试这个,它适用于SQL Server 2005:
select cast(substring(CONTEXT_INFO(), 1, charindex(0x00, CONTEXT_INFO())-1) as varchar(128));
没有杂乱的整理考虑:-)
替换将在SQL服务器的不同安装上随机失败 除非您指定排序规则:
REPLACE(CAST(CONTEXT_INFO() AS varchar(128)) COLLATE Latin1_General_100_BIN , 0x00, '')
SQL Server有两种不同的行为,具体取决于它的安装方式:
- 使用SQL排序规则时,替换成功。
- 使用Windows排序规则时,替换不成功。
这种行为几乎在7年前提交给微软:
问: 尝试替换NUL角色时
使用replace(),这是有效的
value有一个SQL排序规则,但不是
Windows排序规则。
A: 这是由于0x0000的事实
是Windows中未定义的字符
排序规则。所有未定义的字符
在比较期间被忽略,排序,
和模式匹配。所以寻找
'a'+ char(0)正在寻找
'a',搜索char(0)是
相当于空字符串。
处理未定义字符的方法
有点混乱,但这是
Windows定义的排序方式,
和SQL Server符合
一般的Windows API。
在SQL排序规则中,没有概念
未定义的字符。每个代码
为点赋予权重,这就是原因
我们没有看到问题。