2014-01-22 96 views
4

在Microsoft SQL Server中,我試圖通過將varbinary()存儲到上下文信息來將varchar()字符串傳遞給觸發器。如何從SQL Server中的VARCHAR()中刪除尾隨CHAR(0)?

通過CONTEXT_INFO傳遞數據本身不是問題。

我的問題是,我必須轉換到varchar()varbinary()能夠通過數據上下文信息,並轉換回varchar()產生拖尾CHAR(0)人物,我不能妥善處理了。

我試圖找到CHAR(0)的子索引的第一個索引到一個新的正確的字符串,沒有成功。其他內置函數也無法正確處理CHAR(0)字符。

但是:

  • LEN() =>總是返回128,
  • CHARINDEX() =>沒有找到CHAR(0)
  • RTRIM() =>不修剪非打印CHAR(0)字符,
  • REPLACE() =>不替換CHAR(0),
  • 執行異常NG:

    SELECT * FROM (SELECT (@textbin) AS [blabla]) AS [result] FOR XML 
    

特別,我需要傳遞的字符串,如純文本,沒有尾隨空白/ CHAR(0)把字符串XML。

PS .: XML中的BINARY BASE64表示不是我可以使用的選項!

這裏測試SQL腳本

DECLARE @text VARCHAR(128) 
DECLARE @bintext BINARY(128) 
DECLARE @textbin VARCHAR(128) 

SET @text = 'test' 
--SET @text = 'test' + CHAR(0) 
--SET @text = 'test' + CHAR(0) + CHAR(1) 
SET @bintext = CONVERT(BINARY(128), @text) 
SET @textbin = CONVERT(VARCHAR(128), @bintext) 

SET CONTEXT_INFO @bintext 
SET @textbin = CAST(CONTEXT_INFO() AS VARCHAR(128)) 

SELECT 
    @text AS [content], LEN(@text) AS [len], DATALENGTH(@text) AS [datalength] 
    , REVERSE(@text) AS [reverse] 
    , LEN(RTRIM(@text)) AS [len_rtrim] 
    , CHARINDEX(CHAR(0), @text) AS [charindex] 
    , (SELECT * FROM (SELECT @text AS [text]) AS [result] FOR XML AUTO, BINARY BASE64) AS [xml] 
SELECT 
    @bintext AS [content], LEN(@bintext) AS [len], DATALENGTH(@bintext) AS [datalength] 
    , REVERSE(@bintext) AS [reverse] 
    , CHARINDEX(CHAR(0), @bintext) AS [charindex] 
    , (SELECT * FROM (SELECT @bintext AS [bintext]) AS [result] FOR XML AUTO, BINARY BASE64) AS [xml] 
SELECT 
    @textbin AS [content], LEN(@textbin) AS [len], DATALENGTH(@textbin) AS [datalength] 
    , REVERSE(@textbin) AS [reverse] 
    , LEN(LTRIM(@textbin)) AS [len_rtrim] 
    , CHARINDEX(CHAR(0), @textbin) AS [charindex] 
    , (SELECT * FROM (SELECT REPLACE(@textbin, CHAR(0), '?') AS [textbin]) AS [result] FOR XML AUTO, BINARY BASE64) AS [xml] 

IF @textbin = @text 
    SELECT '(@textbin = @text) => TRUE' AS [if] 
ELSE 
    SELECT '(@textbin = @text) => FALSE' AS [if] 

IF @textbin = 'test' 
    SELECT '(@textbin = ''test'') => TRUE' AS [if] 
ELSE 
    SELECT '(@textbin = ''test'') => FALSE' AS [if] 

IF @textbin = 'test' + CHAR(0) + CHAR(1) 
    SELECT '(@textbin = ''test'' + CHAR(0) + CHAR(1)) => TRUE' AS [if] 
ELSE 
    SELECT '(@textbin = ''test'' + CHAR(0) + CHAR(1)) => FALSE' AS [if] 

IF @textbin LIKE 'test' 
    SELECT '(@textbin LIKE ''test'') => TRUE' AS [if] 
ELSE 
    SELECT '(@textbin LIKE ''test'') => FALSE' AS [if] 

IF @textbin LIKE 'test%' 
    SELECT '(@textbin LIKE ''test%'') => TRUE' AS [if] 
ELSE 
    SELECT '(@textbin LIKE ''test%'') => FALSE' AS [if] 

SELECT * FROM (SELECT (@textbin) AS [context_info]) AS [test] FOR XML AUTO, BINARY BASE64 
-- SELECT * FROM (SELECT (@textbin) AS [context_info]) AS [test] FOR XML AUTO, TYPE, BINARY BASE64 
-- SELECT * FROM (SELECT (@textbin) AS [context_info]) AS [test] FOR XML AUTO 

-- relatet to "@textbin" 
-- LEN() => returns always 128, 
-- CHARINDEX() => does not find CHAR(0), 
-- RTRIM() => does not trim non printable CHAR(0) chars, 
-- REPLACE() => does not replace CHAR(0), 
-- exception on executing: SELECT * FROM (SELECT (@textbin) AS [context_info]) AS [test] FOR XML AUTO, TYPE, BINARY BASE64 
-- exception on executing: SELECT * FROM (SELECT (@textbin) AS [context_info]) AS [test] FOR XML AUTO 
+0

嘗試使用DATALENGTH拿到場 – Sameer

+1

的長度我想重複的可以看看這裏http://stackoverflow.com/q/2828333/1692632 – Darka

+0

如果你認爲你需要將數據傳遞給觸發器,這是設計中非常奇怪的事情。您正在使用觸發器,就像它們是存儲過程一樣。 –

回答

0

由於Darka注意到,

這是問題的一個副本: What is the Null Character literal in TSQL?

...謝謝你告訴我。

這種變化固定我的代碼:

SET @textbin = REPLACE(CAST(CAST(CONTEXT_INFO() AS VARCHAR(128)) COLLATE SQL_Latin1_General_CP1_CI_AS AS VARCHAR(128)), CHAR(0), '') 
相關問題