2016-07-14 70 views
3

我試圖將下列有效載荷轉換爲可讀的字符串。 這是一個日誌,其中包含我想用來分析和處理的信息。將有效載荷從VARBINARY轉換爲SQL中的VARCHAR

這是有用消息:

0x234453006AD2C3005B71436C6173733A2061203A3A204173696D6F764661636164652E63616C6C28292072656672657368207B746F6B656E3D65303466663731622D336265342D343836632D623339622D3663633762396365646236397D10070D02040256 

我知道,協議如下:

Header: 3 bytes 
ID: 4 bytes 
Length: 2 bytes 
LogDebug: 1 byte 
LogData: N 
Timestamp: 6 bytes 
CS: 1 byte 

我試着使用:

CONVERT(VARCHAR(MAX), SUBSTRING(payload, 0, 3) + SUBSTRING(payload, 3, 4) + ...) 

,但不能把它上班。我在SSMS文檔中看到,SUBSTRING只接受某些數據類型,例如字符,二進制,文本,ntext或圖像等。 我試圖

CONVERT(VARCHAR(MAX), (SUBSTRING(CONVERT(BINARY,Payload),0, 3)) + (SUBSTRING(CONVERT(BINARY,Payload),3, 4))) 

很好,但沒有運氣:(

任何建議

編輯: 期望的記錄應該是這樣的:

000: ← 2016/07/13 00:04:02, (0x71)U2H.LOGDEBUG - Class: a :: AsimovFacade.call() refresh {token=e04ff71b-3be4-486c-b39b-6cc7b9cedb69} 

我得到:

#DS 
+0

您是否收到任何錯誤消息? – jim

+0

沒有錯誤信息,但輸出太短。我知道輸出應該是什麼。 –

+0

發佈預期輸出樣本,得到錯誤的輸出結果 – Paolo

回答

1

Substring對varbinary正常工作並將返回varbinary。

似乎數據長度字段除了LogData長度之外還包括最後2個字段。

字符串U2H.LOGDEBUG未出現在您的輸入中。

declare @b varbinary(max) = 0x234453006AD2C3005B71436C6173733A2061203A3A204173696D6F764661636164652E63616C6C28292072656672657368207B746F6B656E3D65303466663731622D336265342D343836632D623339622D3663633762396365646236397D10070D02040256 

select cast(substring(@b, 1, 3) as char(3)) as hdr 
select cast(substring(@b, 4, 4) as int) as id 

-- store length of the payload 
declare @len int = cast(substring(@b, 8, 2) as int) 
select @len as length 

select cast(substring(@b, 10, 1) as binary(1)) as logdebug 

-- read payload for the read length, less 7 bytes for the timestamp & cs 
select cast(substring(@b, 11, @len - 7) as varchar(max)) as logdata 

-- read past payload for 6 bytes for the timestamp (whatever format that is - not epoch) 
select substring(@b, @len + 11 - 7, 6) as timestamp 

select substring(@b, @len + 11 - 7 + 6, 1) as cs 

對於

hdr 
---- 
#DS 


id 
----------- 
7000771 


length 
----------- 
91 


logdebug 
-------- 
0x71 


logdata 
---- 
Class: a :: AsimovFacade.call() refresh {token=e04ff71b-3be4-486c-b39b-6cc7b9cedb69} 


timestamp 
---- 
0x10070D020402 


cs 
---- 
0x56 
0

嘗試下面的代碼。幾乎只需要將varbinary子字符串轉換爲協議中的字段,然後轉換爲適當的類型。

我假設你的4字節ID是int,看起來你的長度字段在結尾處包含時間戳和「cs」字段,所以你需要從值中扣除7。

DECLARE @payload varbinary(MAX) = 0x234453006AD2C3005B71436C6173733A2061203A3A204173696D6F764661636164652E63616C6C28292072656672657368207B746F6B656E3D65303466663731622D336265342D343836632D623339622D3663633762396365646236397D10070D02040256 

DECLARE @header char(3), 
     @id  int, 
     @length smallint, 
     @logdebug char(1), 
     @logdata varchar(MAX), 
     @timestamp char(6), 
     @cs   char(1) 

SET @header = convert(char(3), substring(@payload, 1, 3)) 
SET @id = convert(int, substring(@payload, 4, 4)) 
SET @length = convert(smallint, substring(@payload, 8, 2)) - 7 
SET @logdebug = convert(char(1), substring(@payload, 10, 1)) 
SET @logdata = convert(varchar(MAX), substring(@payload, 11, @length)) 
SET @timestamp = convert(char(6), substring(@payload, @length + 11, 6)) 
SET @cs = convert(char(1), substring(@payload, @length + 17, 1)) 



SELECT @header,@id,@length, @logdebug, @logdata, @timestamp, @cs 
相關問題