2013-01-04 3 views
4

시나리오 : 내가 진 필드 (CONTEXT_INFO)에 문자열을 삽입하고 나중에 그것을 밖으로 끌어와 문자열로 다시 변환을 시도하고오른쪽 트리밍 이진 데이터 SQL Server의

. 내가 할 때 결과 문자열은 뒤에 오는 널 문자가 있기 때문에 길이가 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 

질문 :

내가 문자열로 이진 필드를 변환 할 때 어떻게 후행 null 문자를 트리밍 할 수 있습니까?

답변

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),'') 
+0

'SUBSTRING (@string, 127, 1)'을'CHAR (0)'으로 대체하는 것이 더 좋을 것이라고 생각하십니까? – Dan

+0

@ 단 : 물론 이죠. – Kaf

4

여기 내 해결책이 있습니다. CONTEXT_INFO가 값을 어떻게 보이게 만드는지 (오른쪽 패드) 때문에이 방법을 사용했습니다.

기록을 위해
DECLARE @string VARCHAR(128) 
DECLARE @binary VARBINARY(128) 

SET @string = 'abcdefg' 
SET @string = REPLICATE(CHAR(0),128-LEN(@string))[email protected] 
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] 
+0

오 하나님 감사합니다. 나는 오른쪽에 nulls 내 데이터베이스를 작성했습니다. 나는 CONTEXT_INFO를 캐스팅하면서 연주했지만, CONVERT는 그 트릭을했습니다. 예! – jklemmack

1

,이 후행 × 00 트림하고 그들이 데이터의 중간에 일어나는 경우에 장소에 × 00을 떠나 : 당신이 경우

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

이것은하는 VARBINARY 같은 결과를 제공 문자열을 원한다면 바깥 쪽 캐스트를 제거하십시오.

대부분의 다른 솔루션은 중간에 0x00을 제거하거나 0x20으로 변경합니다.

0

nvarchar(x)에서 varbinary(x)으로 돌아 가기 nvarchar(x)에서 항상 왕복 여행을합니다. 여기서 설명한 핵심 문제는 CONTEXT_INFO을 설정하는 데 사용 된 varbinary 소스의 길이에 관계없이 SELECT CONTEXT_INFO()이 항상 128 바이트를 반환하기 때문에 발생합니다.

두 가지 해결 방법이 있습니다.

첫 번째 해결 방법 : SQL 서버 2016 년 시작은 sp_set_session_contextsession_context 광막 우수한을 설정하는 데 사용할 수 있습니다.

두 번째 해결 방법 : context_info는 방법 CONTEXT_INFO()해야 일에 sys.dm_exec_sessions에서 검색 할 수 있습니다.

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 설정 SSMS에서 두 검색 방법을 비교의 여기

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

:이 쿼리는 현재 연결과 관련된 context_info 돌아갑니다 context_infosys.dm_exec_sessions (위에서 볼 수 있듯이 SSMS 배치 구분 기호 GO을 통해)에서 검색하지 못했습니다.