在SQL中将VARBINARY中的有效负载转换为VARCHAR

时间:2016-07-14 15:07:09

标签: sql sql-server tsql

我正在尝试将以下有效内容转换为可读字符串。 它是一个包含我想要在之后用于分析和处理的信息的日志。

这是有效负载消息:

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

2 个答案:

答案 0 :(得分:1)

Substring适用于varbinary并将返回varbinary。

似乎数据长度字段除LogData长度外还包括最后两个字段。

字符串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

答案 1 :(得分: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