一、背景

  前段时间群里的朋友问了一个问题:“在查询时增加一个递增序列,如:0x00000001,即每一个都是36进位(0—9,A--Z),0x0000000Z后面将是0x00000010,生成一个像下面的映射表“:

(Figure1:效果图)

二、十进制转换为十六进制

在网上有很多资料关于使用SQL语句把十进制转换为十六进制的资料,比如:

--方式1
SELECT CONVERT(VARBINARY(50), 23785)

  执行返回值为0x00005CE9,但是需要注意的是,这本应该返回二进制的,但是二进制估计是阅读起来太麻烦,所以SQL Server 返回了十六进制,如果你想要保存为字符串并不是简单把这直接使用CONVERT,类似下面的SQL是不会有返回值的:

SELECT CONVERT(VARCHAR,CONVERT(VARBINARY(50), 23785))

所以网上出现了如下的函数来转换为十六进制的字符串:

--方式2
CREATE FUNCTION Binary2HexStr(@bin VARBINARY(8000))
RETURNS VARCHAR(8000)
AS
BEGIN
DECLARE @re VARCHAR(8000),@i INT
SELECT @re='',@i=datalength(@bin)
WHILE @i>0
SELECT @re=substring('0123456789ABCDEF',substring(@bin,@i,1)/16+1,1)
+substring('0123456789ABCDEF',substring(@bin,@i,1)%16+1,1)
+@re
,@i=@i-1
RETURN('0x'+@re)
END
GO --测试
SELECT dbo.Binary2HexStr(23785)

  上面的SQL同样返回0x00005CE9,但是这次返回的是字符串了,貌似问题都得以解决了,但是,只要你INT值不超过2147483648,这个问题就会出现了,执行下面的SQL返回的结果如Figure2所示:

SELECT dbo.Binary2HexStr(2147483647)
SELECT dbo.Binary2HexStr(2147483648)

(Figure2:数据对比)

从进制的转换运算出发,改进了宋沄剑写了的SQL脚本,修改参数为BIGINT类型:

--方式3
CREATE FUNCTION BigInt2HexStr(@value BIGINT)
RETURNS VARCHAR(50)
AS
BEGIN
DECLARE @seq CHAR(16)
DECLARE @result VARCHAR(50)
DECLARE @digit CHAR(1) SET @seq = '0123456789ABCDEF'
--求十进制的@value除以的余数,找到余数对应十六进制的值
SET @result = SUBSTRING(@seq, (@value%16)+1, 1) WHILE @value > 0
BEGIN
SET @digit = SUBSTRING(@seq, ((@value/16)%16)+1, 1)
SET @value = @value/16
IF @value <> 0
SET @result = @digit + @result
END RETURN @result
END
GO --测试
SELECT dbo.BigInt2HexStr(2147483647)
SELECT dbo.BigInt2HexStr(2147483648)

执行上面的SQL,返回的十六进制如Figure3所示:

(Figure3:数据对比)

  要想理解上面的函数,你需要理解十进制转换为十六进制的运算规则,假如十进制数23785转为十六进制,计算的公式的步骤为:

  1. 23785/16=1486余9,十进制的9对应十六进制的9
  2. 1486/16=92余14,十进制的14对应十六进制的E
  3. 92/16=5余12,十进制的12对应十六进制的C
  4. 5/16=0余5,十进制的5对应十六进制的5

将余数对应的十六进制倒写,即5CE9,所以十进制23785 = 十六进制0x5CE9

三、十进制转换为三十六进制

  通过上面的例子修改下就能支持十进制到三十六进制的转换了:

--十进制转换为十六进制
CREATE FUNCTION BigIntTo36HexStr(@value BIGINT)
RETURNS VARCHAR(50)
AS
BEGIN
DECLARE @seq CHAR(36)
DECLARE @result VARCHAR(50)
DECLARE @digit CHAR(1) SET @seq = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
SET @result = SUBSTRING(@seq, (@value%36)+1, 1) WHILE @value > 0
BEGIN
SET @digit = SUBSTRING(@seq, ((@value/36)%36)+1, 1)
SET @value = @value/36
IF @value <> 0
SET @result = @digit + @result
END RETURN @result
END
GO --测试
SELECT dbo.BigIntTo36HexStr(35)

执行上面的测试SQL,返回0xZ,测试成功;

四、补充说明

  其实编写Binary2HexStr函数是没有必要的,因为SQL Server提供系统的函数支持转换master.dbo.fn_varbintohexstr或者master.dbo.fn_varbintohexsubstring,例如:

SELECT master.dbo.fn_varbintohexstr(2147483647)
SELECT master.dbo.fn_varbintohexsubstring(1,2147483647,1,0)

不过他们一样存在对十进制数据的转换不能超过2147483648的限制。

五、参考文献

SqlServer中varbinary转换成字符串

关于递增序列的问题

进制转换

SQL之36进制转换成10进制数据

SQL Server 中,实现 varbinary 与 varchar 类型之间的数据转换

SQL Server: convert varbinary to varchar

SQL Server 进制转换函数的更多相关文章

  1. php进制转换函数

    1 十进制(decimal system)转换函数 ① 十进制转二进制 string  decbin(int number). 参数为一个十进制整型数字,不是整型数字会自动转为整型数字,如'3'转为3 ...

  2. 写一个比较全的进制转换函数--ic

    //写一个比较全的进制转换函数-----未完成 #include <stdio.h> //D进制转换后 (比如10-2进制) 结果可能会很大 需要很长的字符串来存 #include < ...

  3. Python中进制转换函数的使用

    Python中进制转换函数的使用 关于Python中几个进制转换的函数使用方法,做一个简单的使用方法的介绍,我们常用的进制转换函数常用的就是int()(其他进制转换到十进制).bin()(十进制转换到 ...

  4. C++中的各种进制转换函数汇总

    C++中的各种进制转换函数汇总 1.在C中,按指定进制格式输出如下: #include <iostream> #include <cstdio> using namespace ...

  5. SQL Server进制

    在项目中,大家可能都遇到过,需要把十进制转换为其他进制的情况,google上一搜,已经有很多2进制.8进制.16进制和十进制的转换方法.但是在一些项目中,这些可能无法满足要求,可能需要17.18甚至是 ...

  6. Python内置进制转换函数(实现16进制和ASCII转换)

    在进行wireshark抓包时你会发现底端窗口报文内容左边是十六进制数字,右边是每两个十六进制转换的ASCII字符,这里使用Python代码实现一个十六进制和ASCII的转换方法. hex() 转换一 ...

  7. C++中的各种进制转换函数汇总及学习

    一.指定格式输出 1.C中指定格式输出 printf(); //按八进制格式输出,保留5位高位补零 printf(); //按十进制格式输出,保留3位高位补零 printf(); //按十六进制格式输 ...

  8. chr()//ord() //进制转换函数//eval()//文件函数//split()

    1.chr() 函数 chr() 用一个范围在 range(256)内的(就是0-255)整数作参数,返回一个对应的字符. 用法:chr(i) i可以是10进制也可以是16进制的形式的数字. 2.or ...

  9. c++ 进制转换函数

    转自:https://blog.csdn.net/wangjunchengno2/article/details/78690248 strtol 函数: 它的功能是将一个任意1-36进制数转化为10进 ...

随机推荐

  1. C语言 · 字符转对比

    问题描述 给定两个仅由大写字母或小写字母组成的字符串(长度介于1到10之间),它们之间的关系是以下4中情况之一: 1:两个字符串长度不等.比如 Beijing 和 Hebei 2:两个字符串不仅长度相 ...

  2. TinyWeb v1.0 正式完成第一个Release版本(功能基于 libuv 跨平台库)

    使用方法很简单,很容易融入现有项目,使现有项目拥有Web网站功能和WebSocket,以及Socket直连! 并且包含了一个跨平台(windows/linux)工具集合; 嗯,也挺棒的^,^ 在项目中 ...

  3. Ngrok让你的本地Web应用暴露在公网上

    1.Ngrok介绍 Ngrok是一个反向代理,通过在公共的端点和本地运行的Web服务器之间建立一个安全的通道.Ngrok可捕获和分析所有通道上的流量,便于后期分析和重放.简单来说,利用 Ngrok可以 ...

  4. 深入理解BFC

    定义 在解释BFC之前,先说一下文档流.我们常说的文档流其实分为定位流.浮动流和普通流三种.而普通流其实就是指BFC中的FC.FC是formatting context的首字母缩写,直译过来是格式化上 ...

  5. git-2.10.2-64-bit介绍&&git下载&&git安装教程

    Git介绍 分布式:Git系统是一个分布式的系统,是用来保存工程源代码历史状态的命令行工具. 保存点:Git的保存点可以追踪源码中的文件, 并能得到某一个时间点上的整个工程项目的状态:可以在该保存点将 ...

  6. iOS微信里打开app,Universal Links

    这两天在弄分享,从第三方应用或者浏览器打开自己app的东西 传统的方式是通过URL Scheme的方式,但是iOS9以后又出了新的更完美的方式Universal Links. 传统的URL Schem ...

  7. myeclipse 内存不够用报错PermGen space 和 An internal error has occurred.

    最近项目中又增加了新的模块,项目的代码又多了不少.运行的时候总是报如下错误 Exception in thread "http-apr-80-exec-6" java.lang.O ...

  8. PHP设计模式(七)适配器模式(Adapter For PHP)

    适配器模式:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作. 如下图(借图): // 设置书的接口 // 书接口 interface BookI ...

  9. “风投云涌”:那些被资本看中的IT企业的风光与辛酸

         进入七月份以来,纷享销客获得D轮融资1亿美元,撼动业界,资本与IT联姻令一部分创业者眼红的同时,没有人注意到背后的风险. 科技与资本的结合,是当今经济社会前行的宏大主题.相关统计显示,软件行 ...

  10. BPM配置故事之案例3-参与者与数据自动加载

    这才过了两天,阿海又来了. 阿海:公司决定改进管理方式,以后物资申请的申请人和申请部门要写具体使用人的名字和部门了. 小明:不是要让我改回去吧? 阿海:那太麻烦了,你能不能把申请人改成选择,选好人自动 ...