二进制数据包的解析一般是借助C#等语言,在通讯程序中解析后形成字段,再统一单笔或者批量(表类型参数)提交至数据库,在通讯程序中,存在BINARY到struct再到table的转换。

现借助CLR提供基本的INT2HEX(小端)等函数,在SQL中直接解析数据包。

 

基本函数

  1. [Microsoft.SqlServer.Server.SqlFunction(Name = "Time2UTCBin")]
  2. public
    static SqlBinary Time2UTCBin(DateTime time)
  3. {
  4.     return
    new SqlBinary(BitConverter.GetBytes((uint)(MyTime.ConverDateTimeToJavaMilliSecond(time) / 1000)));
  5. }
  6. [Microsoft.SqlServer.Server.SqlFunction(Name = "UTCBin2Time")]
  7. public
    static SqlDateTime UTCBin2Time(byte[] data,int offset)
  8. {
  9.     return
    new SqlDateTime(MyTime.ConverDateTimeFromJavaMilliSecond(BitConverter.ToUInt32(data, offset) * 1000L));
  10. }
  11.  
  12. [Microsoft.SqlServer.Server.SqlFunction(Name = "getSum")]
  13. public
    static SqlByte Sum(byte[] buffer, int startPos, int endPos)
  14. {
  15.     byte b = 0;
  16.     for (int i = startPos; i <= endPos; i++)
  17.     {
  18.         b ^= buffer[i];
  19.     }
  20.     return b;
  21. }
  22.  
  23. [Microsoft.SqlServer.Server.SqlFunction(Name = "updateSum")]
  24. public
    static SqlBinary updateSum(byte[] buffer, int startPos, int endPos, int sumPos)
  25. {
  26.     byte b = 0;
  27.     for (int i = startPos; i <= endPos; i++)
  28.     {
  29.         b ^= buffer[i];
  30.     }
  31.     buffer[sumPos] = b;
  32.     return
    new SqlBinary(buffer);
  33. }
  34.  
  35.  
  36. [Microsoft.SqlServer.Server.SqlFunction(Name = "Int2Bin")]
  37. public
    static SqlBinary Int2Bin(int number)
  38. {
  39.     return
    new SqlBinary(BitConverter.GetBytes(number));
  40. }
  41.  
  42. [Microsoft.SqlServer.Server.SqlFunction(Name = "Long2Bin")]
  43. public
    static SqlBinary Long2Bin(long number)
  44. {
  45.     return
    new SqlBinary(BitConverter.GetBytes(number));
  46. }
  47. [Microsoft.SqlServer.Server.SqlFunction(Name = "Bin2Int")]
  48. public
    static SqlInt32 Bin2Int(byte[] data, int offset)
  49. {
  50.     return
    new SqlInt32(BitConverter.ToInt32(data,offset));
  51. }
  52. [Microsoft.SqlServer.Server.SqlFunction(Name = "Bin2Long")]
  53. public
    static SqlInt64 Bin2Long(byte[] data, int offset)
  54. {
  55.     return
    new SqlInt64(BitConverter.ToInt64(data, offset));
  56. }
  57. [Microsoft.SqlServer.Server.SqlFunction(Name = "getByte")]
  58. public
    static SqlByte getByte(byte[] data, int offset)
  59. {
  60.     return
    new SqlByte(data[offset]);
  61. }
  62. [Microsoft.SqlServer.Server.SqlFunction(Name = "getBytes")]
  63. public
    static SqlBytes getBytes(byte[] data, int offset,int count)
  64. {
  65.     byte[] temp = new
    byte[count];
  66.     Array.Copy(data, offset, temp, 0, count);
  67.     return
    new SqlBytes(temp);
  68. }

 

 

数据包的结构体(表类型)

  1. --交易扩展记录
  2. CREATE TYPE [dbo].[DeviceTranscationEMV] AS
    TABLE
  3. (
  4. [RawData] VARBINARY(200) NOT
    NULL,
  5. [EMVType] TINYINT
    NOT
    NULL,
  6. [EMVNO] SMALLINT
    NOT
    NULL,
  7. [HardwareNo] INT
    NOT
    NULL,
  8. Meter INT,
  9. run INT,
  10. dead INT,
  11. StartTime DATETIME ,
  12. EndTime DATETIME
  13. )

 

 

SQL中借助CLR实现的转换函数

 

  1. CREATE
    FUNCTION [dbo].[Binary2EMVTaxi]
  2.     (
  3.       @data VARBINARY(MAX) ,
  4.       @offset INT = 1 ,
  5.       @withDeviceID BIT = 0
  6.     )
  7.     (
  8.       [RawData] BINARY(72) NOT
    NULL ,
  9.       [DeviceID] UNIQUEIDENTIFIER ,
  10.       [EMVType] TINYINT
    NOT
    NULL ,
  11.       [EMVNO] SMALLINT
    NOT
    NULL ,
  12.       [HardwareNo] INT
    NOT
    NULL ,
  13.       Meter INT ,
  14.       run INT ,
  15.       WORK
    INT ,
  16.       dead INT ,
  17.       StartTime DATETIME ,
  18.       EndTime DATETIME
  19.     )
  20.     BEGIN
  21.         DECLARE @c INT
  22.         DECLARE @size
    INT
  23.         DECLARE @sized INT
  24.  
  25.         IF @withdeviceid = 1
  26.             BEGIN
  27.                 SET @sized = 16
  28.                 SET @size = 72 + @sized
  29.             END
  30.         ELSE
  31.             BEGIN
  32.                 SET @sized = 0
  33.                 SET @size = 72
  34.             END
  35.  
  36.         SET @c = DATALENGTH(@data) / @size;
  37.  
  38.         WITH sub
  39.                   AS ( SELECT
    SUBSTRING(@data, 1 + id * @size + @offset,
  40.                                           @size) binDATA
  41.                        FROM sys_id
  42.                        WHERE id < @c
  43.                      )
  44.             INSERT @emv
  45.                     ( rawdata ,
  46.                       DeviceID ,
  47.                       hardwareno ,
  48.                       meter ,
  49.                       run ,
  50.                       WORK ,
  51.                       dead ,
  52.                       starttime ,
  53.                       endtime ,
  54.                       emvtype ,
  55.                       emvno
  56.                     )
  57.                     SELECT
    CASE @withDeviceID
  58.                               WHEN 0 THEN bindata
  59.                               ELSE
    SUBSTRING(bindata, 1 + @sized, @size)
  60.                             END ,
  61.                             CASE @withDeviceID
  62.                               WHEN 0 THEN
    NULL
  63.                               ELSE
    CAST (SUBSTRING(bindata, 1, @sized) AS
    UNIQUEIDENTIFIER)
  64.                             END ,
  65.                             dbo.Bin2Int(bindata, 0 + @sized) RecordNo ,
  66.                             dbo.Bin2Int(bindata, 4 + @sized) Meter ,
  67.                             dbo.Bin2Int(bindata, 8 + @sized) run ,
  68.                             dbo.Bin2Int(bindata, 12 + @sized) WORK ,
  69.                             dbo.Bin2Int(bindata, 16 + @sized) dead ,
  70.                             dbo.utcbin2time(bindata, 20 + @sized) StartTime ,
  71.                             dbo.utcbin2time(bindata, 24 + @sized) EndTime ,
  72.                             dbo.getByte(bindata, 61 + @sized) RecordType ,
  73.                             dbo.getByte(bindata, 62 + @sized) EMVNo
  74.                     FROM sub
  75.         RETURN
  76.     END

 

  1. CREATE
    FUNCTION [dbo].[EMVTaxi2Binary]
  2.     (
  3.       @emv DeviceTranscationEMV READONLY ,
  4.       @withDeviceID BIT = 0
  5.     )
  6.     BEGIN
  7.         DECLARE @bin VARBINARY(MAX)
  8.         SET @bin = 0x0
  9.         IF @withDeviceID = 0
  10.             SELECT @bin = @bin + dbo.updatesum(dbo.int2Bin([HardwareNo])
  11.                                                 + dbo.int2Bin(meter)
  12.                                                 + dbo.int2Bin(run)
  13.                                                 + dbo.int2Bin(work)
  14.                                                 + dbo.int2Bin(dead)
  15.                                                 + dbo.time2utcbin(starttime)
  16.                                                 + dbo.time2utcbin(endtime)
  17.                                                 + CAST(0 AS
    BINARY(33))
  18.                                                 + CAST(emvtype AS
    BINARY(1))
  19.                                                 + CAST(emvno AS
    BINARY(1))
  20.                                                 + CAST (0 AS
    BINARY(1))
  21.                                                 + CAST(0 AS
    BINARY(7)) + 0x55,
  22.                                                 0, 62, 63)
  23.             FROM @emv
  24.  
  25.         ELSE
  26.             SELECT @bin = @bin + CAST (deviceid AS
    BINARY(16))
  27.                     + dbo.updatesum(dbo.int2Bin([HardwareNo])
  28.                                     + dbo.int2Bin(meter) + dbo.int2Bin(run)
  29.                                     + dbo.int2Bin(work) + dbo.int2Bin(dead)
  30.                                     + dbo.time2utcbin(starttime)
  31.                                     + dbo.time2utcbin(endtime)
  32.                                     + CAST(0 AS
    BINARY(33))
  33.                                     + CAST(emvtype AS
    BINARY(1))
  34.                                     + CAST(emvno AS
    BINARY(1))
  35.                                     + CAST (0 AS
    BINARY(1))
  36.                                     + CAST(0 AS
    BINARY(7)) + 0x55, 0, 62, 63)
  37.             FROM @emv
  38.  
  39.         RETURN @bin
  40.     END

 

 

测试代码

 

  1. PRINT N'构造EMV数据,转换为BIN,然后再转换回EMV数据'
  2. go
  3. DECLARE @emv DeviceTranscationEMV
  4. WITH data
  5.           AS ( SELECT id RecordNo ,
  6.                         15 Meter ,
  7.                         100 run ,
  8.                         80 WORK ,
  9.                         20 dead ,
  10.                         DATEADD(s, id, '2014-9-1 12:50:01') StartTime ,
  11.                         DATEADD(mi, id, '2014-9-1 13:23:11') EndTime ,
  12.                         4 RecordType ,
  13.                         0 EMVNo
  14.                FROM dbo.Sys_ID
  15.                WHERE id < 100
  16.              )
  17.     INSERT
    INTO @emv
  18.             ( rawdata ,
  19.               deviceid ,
  20.               emvtype ,
  21.               emvno ,
  22.               hardwareno ,
  23.               meter ,
  24.               run ,
  25.               work ,
  26.               dead ,
  27.               starttime ,
  28.               endtime
  29.             )
  30.             SELECT 0x00 ,
  31.                     NEWID() ,
  32.                     recordtype ,
  33.                     emvno ,
  34.                     recordno ,
  35.                     meter ,
  36.                     run ,
  37.                     work ,
  38.                     dead ,
  39.                     starttime ,
  40.                     EndTime
  41.             FROM data
  42. FROM @emv
  43.  
  44. SELECT @data = dbo.emvtaxi2binary(@emv, 1)
  45. PRINT @data
  46.  
  47.  
  48. FROM dbo.binary2emvtaxi(@data, 1, 1)

 

 

执行结果:

 

 

 

 

资源:

 

 

 

 

在SQL中使用CLR提供基本函数对二进制数据进行解析与构造的更多相关文章

  1. sql中根据逗号分隔,查出多行数据

    --sql中根据逗号分隔,查出多行数据 select       a.DiscussID,b.LocationID  from       (select DiscussID,LocationID=c ...

  2. sql中的 where 、group by 和 having 用法解析

    --sql中的 where .group by 和 having 用法解析 --如果要用到group by 一般用到的就是“每这个字” 例如说明现在有一个这样的表:每个部门有多少人 就要用到分组的技术 ...

  3. ORA-01406:提取的列值被截断 ; SQL Server :将截断字符串或二进制数据

    oracle 数据库可以正常连接,表数据也可以正常读取, 但在程序中相同的位置,有时会报错,有时不会报错,有的电脑会报错,有的不会 报错内容为 ORA-01406:提取的列值被截断 查了网上提供的一些 ...

  4. 在SQL中直接把查询结果转换为JSON数据

    下面这篇中,已经有准备一些数据: <MS SQL server对象类型type>https://www.cnblogs.com/insus/p/10903916.html 为前端服务,直接 ...

  5. SQL中 根据行号设置每行数据的排序数值

    根据行号自动把当前行号插入到某列中 实现排序 update tempTable set DisplayOrder = right( CAST(rownum as NVARCHAR),5) from(  ...

  6. sql中关闭自增,并插入数据

    ET IDENTITY_INSERT 允许将显式值插入表的标识列中. 语法 SET IDENTITY_INSERT [ database.[ owner.] ] { table } { ON | OF ...

  7. sql 中如何查询某一列的数据在另一个表中有没有?

    假设表table1,列a,表table2,列bselect a from table1where a not in(select b from table2)

  8. Sql 中的as是什么意思 + 无列名注入解析

    相当于取别名 这里结合一下无列名注入的知识点: 这种方法在第十届SWPUCTF的web1——广告招租里考到了:

  9. SQL中采用Newtonsoft.Json处理json字符串

    原文 SQL中采用Newtonsoft.Json处理json字符串 使用环境: SQL Server2005; VS2010; 关于SQL中部署CLR程序集的方法,网上一搜一大把,需要了解的自行查阅, ...

随机推荐

  1. child-selector解释

    这个伪类选择器应该叫孩子选择器,意思是选择网页中所有父节点的第一个子节点,并且这第一个子字节点必须是指定标签元素 写法有 :first-child :last-child :nth-child(odd ...

  2. JS框架avalon简单例子 行编辑 添加 修改 删除 验证

    为什么要写这个例子:做表单的时候,表单包含主子表,对于子表的编辑,使用的是easyui datagrid的行编辑功能,由于业务比较复杂,实现起来比较麻烦,代码写的也很多,因为插件的封装,无法操作原始的 ...

  3. Asp.Net WebForm和MVC同样优秀!

    不是说MVC不好,而是WebForm并没有那么不堪,和Mvc同样优秀.对说WebForm缺点多的,表示不服,求指教,虽然本人有些见解可能比较浅薄. 看过很多文章和书籍,都会拿MVC模式和WebForm ...

  4. ASP.NET MVC 请求流程

    一.应用程序启动 1.Application_Start方法,程序启动 2.RegisterRoutes方法,注册路由 3.System.Web.Mvc.RouteCollectionExtensio ...

  5. C#-INotifyPropertyChanged(解决数据绑定的界面刷新问题)

    最近做项目用到DataGridView,用它绑定数据源后,如果数据源中的数据修改无法及时刷新到控件上,必须切换单元格的焦点才能导致刷新显示新数值,通过查官方文档,用INotifyPropertyCha ...

  6. MySQL函数不能创建的解决方法

    MySQL函数不能创建,是一个很麻烦的问题,下面就为您提供了一个解决此问题的方法,如果您也遇到过类似的问题,不妨一看. http://database.51cto.com/art/201010/229 ...

  7. 【转】数据库无关的GO语言ORM - hood

    项目地址:https://github.com/eaigner/hood 这是一个极具美感的ORM库. 特性 链式的api 事务支持 迁移和名字空间生成 模型变量 模型时间 数据库方言接口 没有含糊的 ...

  8. Python中的编码

    http://liguangming.com/how-to-use-utf-8-with-python http://www.lijiejie.com/python-sys-setdefaultenc ...

  9. tp5页面输出时,搜索后跳转下一页的处理

    tp5页面输出时,搜索功能在跳转下一页时,如果不做任何处理,会返回原有是第二页输出的数据.为了保证跳转下一页时输出的是搜索到的数据,做以下处理. (要根据自己的搜索字段进行适当修改) 页面js代码,给 ...

  10. 在腾讯云上面搭建WordPress博客网站

    一.准备工作 我们使用腾讯云服务器来运行WordPress,腾讯云会给新用户七天的产品体验时间还有一些代金券,做为新手尝试成本是比较小的. 腾讯云长期举办 "云+校园" 活动,学生 ...