情境:
我将字符串插入二进制字段(CONTEXT_INFO),然后尝试将其拉出并将其转换回字符串。当我这样做时,结果字符串的长度为128,因为它具有尾随空字符。
示例:
DECLARE @string VARCHAR(128)
DECLARE @binary VARBINARY(128)
SET @string = 'abcdefg'
SET @binary = CONVERT(VARBINARY(128), @string) --0x61626364656667000000...
SET CONTEXT_INFO @binary
SET @binary = CONTEXT_INFO()
-- I would like to change the following line so it trims trailing null chars
SET @string = CONVERT(VARCHAR(128), @binary)
SELECT
@binary AS [binary],
DATALENGTH(@binary) AS [binary.Length], --128 as expected
@string AS [string],
DATALENGTH(@string) AS [string.Length] --This is 128, but I need it to be 7
问题:
当我将二进制字段转换为字符串时,如何修剪尾随的空字符?
答案 0 :(得分:4)
试试这个,works on Sql-Server 2008.
这是Sql Fiddle。
请注意,我假设原始字符串中没有Char(0),因为这可以简单地替换原始字符串。
-- I would like to change the following line so it trims trailing null chars
SET @string = CONVERT(VARCHAR(128), @binary)
SET @string = REPLACE(@string, Char(0),'')
答案 1 :(得分:4)
这是我的解决方案。我这样做是因为CONTEXT_INFO使值看起来像(右边的垫)。
DECLARE @string VARCHAR(128)
DECLARE @binary VARBINARY(128)
SET @string = 'abcdefg'
SET @string = REPLICATE(CHAR(0),128-LEN(@string))+@string
SET @binary = CONVERT(VARBINARY(128), @string)
SET CONTEXT_INFO @binary
SET @binary = CONTEXT_INFO()
SET @string = CONVERT(VARCHAR(128), REPLACE(@binary,CHAR(0),''))
SELECT
@binary AS [binary],
DATALENGTH(@binary) AS [binary.Length],
@string AS [string],
DATALENGTH(@string) AS [string.Length]
答案 2 :(得分:1)
对于记录,如果它们发生在数据中间,这将修剪尾随的0x00并保留0x00:
cast(substring(CONTEXT_INFO(), 1, len(REPLACE(REPLACE(CONTEXT_INFO(), 0x20, 0x21), 0x00, 0x20))) as varbinary(128))
这给出了一个varbinary结果,如果你想要一个字符串,删除外部强制转换
大多数其他解决方案要么最终删除中间的0x00,要么将其更改为0x20。
答案 3 :(得分:0)
从nvarchar(x)
转换为varbinary(x)
返回nvarchar(x)
将始终正确往返。此处描述的核心问题是因为SELECT CONTEXT_INFO()
始终返回128个字节,而不管用于设置CONTEXT_INFO
的varbinary源的长度如何。
有两种解决方法。
第一种解决方法:从SQL Server 2016开始,sp_set_session_context
可用于设置极高的session_context
。
第二种解决方法:context_info
可以CONTEXT_INFO()
的方式从sys.dm_exec_sessions
检索context_info
。此查询将返回与当前连接关联的SELECT context_info FROM sys.dm_exec_sessions WHERE session_id = @@SPID
:
SET CONTEXT_INFO 0x010200340056;
GO
SELECT CONTEXT_INFO(); -- 0x0012003400560000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
SELECT context_info FROM sys.dm_exec_sessions WHERE session_id = @@SPID; -- 0x001200340056
SET CONTEXT_INFO 0x;
GO
SELECT CONTEXT_INFO(); -- NULL
SELECT context_info FROM sys.dm_exec_sessions WHERE session_id = @@SPID; -- 0x
这里是SSMS中两种检索方法的比较:
CONTEXT_INFO
警告:设置context_info
应该分批执行,而不是通过sys.dm_exec_sessions
检索GO
(如上所示,通过SSMS批处理分隔符{{ 1}})。