在SQL中使用CLR提供基本函数对二进制数据进行解析与构造
时间:2022-03-13 23:45
?
二进制数据包的解析一般是借助C#等语言,在通讯程序中解析后形成字段,再统一单笔或者批量(表类型参数)提交至数据库,在通讯程序中,存在BINARY到struct再到table的转换。
现借助CLR提供基本的INT2HEX(小端)等函数,在SQL中直接解析数据包。
?
基本函数
- [Microsoft.SqlServer.Server.SqlFunction(Name = "Time2UTCBin")]
- public static SqlBinary Time2UTCBin(DateTime time)
- {
- ????return new SqlBinary(BitConverter.GetBytes((uint)(MyTime.ConverDateTimeToJavaMilliSecond(time) / 1000)));
- }
- [Microsoft.SqlServer.Server.SqlFunction(Name = "UTCBin2Time")]
- public static SqlDateTime UTCBin2Time(byte[] data,int offset)
- {
- ????return new SqlDateTime(MyTime.ConverDateTimeFromJavaMilliSecond(BitConverter.ToUInt32(data, offset) * 1000L));
- }
- ?
- [Microsoft.SqlServer.Server.SqlFunction(Name = "getSum")]
- public static SqlByte Sum(byte[] buffer, int startPos, int endPos)
- {
- ????byte b = 0;
- ????for (int i = startPos; i <= endPos; i++)
- ????{
- ????????b ^= buffer[i];
- ????}
- ????return b;
- }
- ?
- [Microsoft.SqlServer.Server.SqlFunction(Name = "updateSum")]
- public static SqlBinary updateSum(byte[] buffer, int startPos, int endPos, int sumPos)
- {
- ????byte b = 0;
- ????for (int i = startPos; i <= endPos; i++)
- ????{
- ????????b ^= buffer[i];
- ????}
- ????buffer[sumPos] = b;
- ????return new SqlBinary(buffer);
- }
- ?
- ?
- [Microsoft.SqlServer.Server.SqlFunction(Name = "Int2Bin")]
- public static SqlBinary Int2Bin(int number)
- {
- ????return new SqlBinary(BitConverter.GetBytes(number));
- }
- ?
- [Microsoft.SqlServer.Server.SqlFunction(Name = "Long2Bin")]
- public static SqlBinary Long2Bin(long number)
- {
- ????return new SqlBinary(BitConverter.GetBytes(number));
- }
- [Microsoft.SqlServer.Server.SqlFunction(Name = "Bin2Int")]
- public static SqlInt32 Bin2Int(byte[] data, int offset)
- {
- ????return new SqlInt32(BitConverter.ToInt32(data,offset));
- }
- [Microsoft.SqlServer.Server.SqlFunction(Name = "Bin2Long")]
- public static SqlInt64 Bin2Long(byte[] data, int offset)
- {
- ????return new SqlInt64(BitConverter.ToInt64(data, offset));
- }
- [Microsoft.SqlServer.Server.SqlFunction(Name = "getByte")]
- public static SqlByte getByte(byte[] data, int offset)
- {
- ????return new SqlByte(data[offset]);
- }
- [Microsoft.SqlServer.Server.SqlFunction(Name = "getBytes")]
- public static SqlBytes getBytes(byte[] data, int offset,int count)
- {
- ????byte[] temp = new byte[count];
- ????Array.Copy(data, offset, temp, 0, count);
- ????return new SqlBytes(temp);
- }
?
?
数据包的结构体(表类型)
- --交易扩展记录
- TYPE [dbo].[DeviceTranscationEMV]
- (
- [RawData] (200) ,
- [DeviceID] ,
- [EMVType] ,
- [EMVNO] ,
- [HardwareNo] ,
- Meter ,
- run ,
- ,
- dead ,
- StartTime ,
- EndTime
- )
?
?
SQL中借助CLR实现的转换函数
?
- [dbo].[2EMVTaxi]
- ????(
- ??????@data () ,
- ??????@offset = 1 ,
- ??????@withDeviceID = 0
- ????)
- @emv
- ????(
- ??????[RawData] (72) ,
- ??????[DeviceID] ,
- ??????[EMVType] ,
- ??????[EMVNO] ,
- ??????[HardwareNo] ,
- ??????Meter ,
- ??????run ,
- ?????? ,
- ??????dead ,
- ??????StartTime ,
- ??????EndTime
- ????)
- ????
- ???????? @c
- ???????? @
- ???????? @sized
- ?
- ???????? @withdeviceid = 1
- ????????????
- ???????????????? @sized = 16
- ???????????????? @ = 72 + @sized
- ????????????
- ????????
- ????????????
- ???????????????? @sized = 0
- ???????????????? @ = 72
- ????????????
- ?
- ???????? @c = DATALENGTH(@data) / @;
- ?
- ???????? sub
- ?????????????????? ( (@data, 1 + id * @ + @offset,
- ??????????????????????????????????????????@) binDATA
- ??????????????????????? sys_id
- ??????????????????????? id < @c
- ?????????????????????)
- ???????????? @emv
- ????????????????????( rawdata ,
- ??????????????????????DeviceID ,
- ??????????????????????hardwareno ,
- ??????????????????????meter ,
- ??????????????????????run ,
- ?????????????????????? ,
- ??????????????????????dead ,
- ??????????????????????starttime ,
- ??????????????????????endtime ,
- ??????????????????????emvtype ,
- ??????????????????????emvno
- ????????????????????)
- ???????????????????? @withDeviceID
- ?????????????????????????????? 0 bindata
- ?????????????????????????????? (bindata, 1 + @sized, @)
- ???????????????????????????? ,
- ???????????????????????????? @withDeviceID
- ?????????????????????????????? 0
- ?????????????????????????????? ((bindata, 1, @sized) )
- ???????????????????????????? ,
- ????????????????????????????dbo.Bin2(bindata, 0 + @sized) RecordNo ,
- ????????????????????????????dbo.Bin2(bindata, 4 + @sized) Meter ,
- ????????????????????????????dbo.Bin2(bindata, 8 + @sized) run ,
- ????????????????????????????dbo.Bin2(bindata, 12 + @sized) ,
- ????????????????????????????dbo.Bin2(bindata, 16 + @sized) dead ,
- ????????????????????????????dbo.utcbin2(bindata, 20 + @sized) StartTime ,
- ????????????????????????????dbo.utcbin2(bindata, 24 + @sized) EndTime ,
- ????????????????????????????dbo.getByte(bindata, 61 + @sized) RecordType ,
- ????????????????????????????dbo.getByte(bindata, 62 + @sized) EMVNo
- ???????????????????? sub
- ????????
- ????
?
- [dbo].[EMVTaxi2]
- ????(
- ??????@emv DeviceTranscationEMV READONLY ,
- ??????@withDeviceID = 0
- ????)
- ()
- ????
- ???????? @bin ()
- ???????? @bin = 0x0
- ???????? @withDeviceID = 0
- ???????????? @bin = @bin + dbo.updatesum(dbo.2Bin([HardwareNo])
- ????????????????????????????????????????????????+ dbo.2Bin(meter)
- ????????????????????????????????????????????????+ dbo.2Bin(run)
- ????????????????????????????????????????????????+ dbo.2Bin()
- ????????????????????????????????????????????????+ dbo.2Bin(dead)
- ????????????????????????????????????????????????+ dbo.2utcbin(starttime)
- ????????????????????????????????????????????????+ dbo.2utcbin(endtime)
- ????????????????????????????????????????????????+ (0 (33))
- ????????????????????????????????????????????????+ (emvtype (1))
- ????????????????????????????????????????????????+ (emvno (1))
- ????????????????????????????????????????????????+ (0 (1))
- ????????????????????????????????????????????????+ (0 (7)) + 0x55,
- ????????????????????????????????????????????????0, 62, 63)
- ???????????? @emv
- ?
- ????????
- ???????????? @bin = @bin + (deviceid (16))
- ????????????????????+ dbo.updatesum(dbo.2Bin([HardwareNo])
- ????????????????????????????????????+ dbo.2Bin(meter) + dbo.2Bin(run)
- ????????????????????????????????????+ dbo.2Bin() + dbo.2Bin(dead)
- ????????????????????????????????????+ dbo.2utcbin(starttime)
- ????????????????????????????????????+ dbo.2utcbin(endtime)
- ????????????????????????????????????+ (0 (33))
- ????????????????????????????????????+ (emvtype (1))
- ????????????????????????????????????+ (emvno (1))
- ????????????????????????????????????+ (0 (1))
- ????????????????????????????????????+ (0 (7)) + 0x55, 0, 62, 63)
- ???????????? @emv
- ?
- ???????? @bin
- ????
?
?
测试代码
?
- N‘构造EMV数据,转换为BIN,然后再转换回EMV数据‘
- go
- @emv DeviceTranscationEMV
- data
- ?????????? ( id RecordNo ,
- ????????????????????????15 Meter ,
- ????????????????????????100 run ,
- ????????????????????????80 ,
- ????????????????????????20 dead ,
- ????????????????????????DATEADD(s, id, ‘2014-9-1 12:50:01‘) StartTime ,
- ????????????????????????DATEADD(mi, id, ‘2014-9-1 13:23:11‘) EndTime ,
- ????????????????????????4 RecordType ,
- ????????????????????????0 EMVNo
- ??????????????? dbo.Sys_ID
- ??????????????? id < 100
- ?????????????)
- ???? @emv
- ????????????( rawdata ,
- ??????????????deviceid ,
- ??????????????emvtype ,
- ??????????????emvno ,
- ??????????????hardwareno ,
- ??????????????meter ,
- ??????????????run ,
- ?????????????? ,
- ??????????????dead ,
- ??????????????starttime ,
- ??????????????endtime
- ????????????)
- ???????????? 0x00 ,
- ????????????????????NEWID() ,
- ????????????????????recordtype ,
- ????????????????????emvno ,
- ????????????????????recordno ,
- ????????????????????meter ,
- ????????????????????run ,
- ???????????????????? ,
- ????????????????????dead ,
- ????????????????????starttime ,
- ????????????????????EndTime
- ???????????? data
- *
- @emv
- @data ()
- ?
- @data = dbo.emvtaxi2(@emv, 1)
- @data
- ?
- ?
- *
- dbo.2emvtaxi(@data, 1, 1)
?
?
执行结果:
?
?
?
?
资源:
?
?
?
?