5

设想:

我将一个字符串插入二进制字段(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

问题:

将二进制字段转换为字符串时,如何修剪尾随的空字符?

4

4 回答 4

6

试试这个,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),'') 
于 2013-01-04T18:40:41.463 回答
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]
于 2013-01-04T18:45:35.413 回答
2

作为记录,如果它们发生在数据中间,这将修剪尾随 0x00 并保留 0x00:

cast(substring(CONTEXT_INFO(), 1, len(REPLACE(REPLACE(CONTEXT_INFO(), 0x20, 0x21), 0x00, 0x20))) as varbinary(128))

这给出了一个 varbinary 的结果,如果你想要一个字符串,请删除外部演员

大多数其他解决方案要么最终删除中间的 0x00,要么将其更改为 0x20。

于 2015-06-18T16:12:20.887 回答
0

nvarchar(x)转换varbinary(x)回到nvarchar(x)将始终正确往返。出现此处描述的核心问题是因为SELECT CONTEXT_INFO()始终返回 128 个字节,而不管用于 set 的 varbinary 源的长度如何CONTEXT_INFO

有两种解决方法。

第一种解决方法:从 SQL Server 2016 开始,sp_set_session_context可用于设置非常优越的session_context.

第二种解决方法context_info可以从应该工作sys.dm_exec_sessions的方式中检索。此查询将返回与当前连接关联的:CONTEXT_INFO() context_info

SELECT context_info FROM sys.dm_exec_sessions WHERE session_id = @@SPID

下面是SSMS中两种检索方式的对比:

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

警告:设置CONTEXT_INFO应在与通过检索分开的批次中执行context_infosys.dm_exec_sessions如上所示,通过 SSMS 批次分隔符GO)。

于 2016-04-28T03:25:13.433 回答