将CONTEXT_INFO转换为varchar以及生成的长度

时间:2012-02-24 16:47:00

标签: sql-server sql-server-2005 varchar varbinary context-info

我正在尝试使用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年以后的所有版本中运行。

4 个答案:

答案 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有两种不同的行为,具体取决于它的安装方式:

  • 使用SQL排序规则时,替换成功。
  • 使用Windows排序规则时,替换功能失败。

此行为是在近7年前提交给Microsoft的:

  

问:尝试更换NUL字符时   使用replace(),这是有效的   value有一个SQL排序规则,但不是   Windows排序规则。

     

A:这是因为0x0000   是Windows中未定义的字符   排序规则。所有未定义的字符   在比较期间被忽略,排序,   和模式匹配。所以寻找   'a'+ char(0)正在寻找   'a',搜索char(0)是   相当于空字符串。

     

处理未定义字符的方法   有点混乱,但这是   Windows定义的排序方式,   和SQL Server符合   一般的Windows API。

     

在SQL排序规则中,没有概念   未定义的字符。每个代码   点被赋予权重,这就是原因   我们没有看到问题。