SQL Server 进制转换函数
一、背景
前段时间群里的朋友问了一个问题:“在查询时增加一个递增序列,如: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转为十六进制,计算的公式的步骤为:
- 23785/16=1486余9,十进制的9对应十六进制的9;
- 1486/16=92余14,十进制的14对应十六进制的E;
- 92/16=5余12,十进制的12对应十六进制的C;
- 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的限制。
五、参考文献
SQL Server 中,实现 varbinary 与 varchar 类型之间的数据转换
SQL Server: convert varbinary to varchar
SQL Server 进制转换函数的更多相关文章
- php进制转换函数
1 十进制(decimal system)转换函数 ① 十进制转二进制 string decbin(int number). 参数为一个十进制整型数字,不是整型数字会自动转为整型数字,如'3'转为3 ...
- 写一个比较全的进制转换函数--ic
//写一个比较全的进制转换函数-----未完成 #include <stdio.h> //D进制转换后 (比如10-2进制) 结果可能会很大 需要很长的字符串来存 #include < ...
- Python中进制转换函数的使用
Python中进制转换函数的使用 关于Python中几个进制转换的函数使用方法,做一个简单的使用方法的介绍,我们常用的进制转换函数常用的就是int()(其他进制转换到十进制).bin()(十进制转换到 ...
- C++中的各种进制转换函数汇总
C++中的各种进制转换函数汇总 1.在C中,按指定进制格式输出如下: #include <iostream> #include <cstdio> using namespace ...
- SQL Server进制
在项目中,大家可能都遇到过,需要把十进制转换为其他进制的情况,google上一搜,已经有很多2进制.8进制.16进制和十进制的转换方法.但是在一些项目中,这些可能无法满足要求,可能需要17.18甚至是 ...
- Python内置进制转换函数(实现16进制和ASCII转换)
在进行wireshark抓包时你会发现底端窗口报文内容左边是十六进制数字,右边是每两个十六进制转换的ASCII字符,这里使用Python代码实现一个十六进制和ASCII的转换方法. hex() 转换一 ...
- C++中的各种进制转换函数汇总及学习
一.指定格式输出 1.C中指定格式输出 printf(); //按八进制格式输出,保留5位高位补零 printf(); //按十进制格式输出,保留3位高位补零 printf(); //按十六进制格式输 ...
- chr()//ord() //进制转换函数//eval()//文件函数//split()
1.chr() 函数 chr() 用一个范围在 range(256)内的(就是0-255)整数作参数,返回一个对应的字符. 用法:chr(i) i可以是10进制也可以是16进制的形式的数字. 2.or ...
- c++ 进制转换函数
转自:https://blog.csdn.net/wangjunchengno2/article/details/78690248 strtol 函数: 它的功能是将一个任意1-36进制数转化为10进 ...
随机推荐
- RabbitMq应用二
在应用一中,基本的消息队列使用已经完成了,在实际项目中,一定会出现各种各样的需求和问题,rabbitmq内置的很多强大机制和功能会帮助我们解决很多的问题,下面就一个一个的一起学习一下. 消息响应机制 ...
- NYOJ 1007
在博客NYOJ 998 中已经写过计算欧拉函数的三种方法,这里不再赘述. 本题也是对欧拉函数的应用的考查,不过考查了另外一个数论基本定理:如何用欧拉函数求小于n且与n互质所有的正整数的和. 记eule ...
- 简单有效的kmp算法
以前看过kmp算法,当时接触后总感觉好深奥啊,抱着数据结构的数啃了一中午,最终才大致看懂,后来提起kmp也只剩下“奥,它是做模式匹配的”这点干货.最近有空,翻出来算法导论看看,原来就是这么简单(先不说 ...
- 算法与数据结构(十六) 快速排序(Swift 3.0版)
上篇博客我们主要聊了比较高效的归并排序算法,本篇博客我们就来介绍另一种高效的排序算法:快速排序.快速排序的思想与归并排序类似,都是采用分而治之的方式进行排序的.快速排序的思想主要是取出无序序列中第一个 ...
- iOS逆向工程之Theos
如果你对iOS逆向工程有所了解,那么你对Tweak并不陌生.那么由Tweak我们又会引出Theos, 那么什么是Theos呢,简单一句话,Theos是一个越狱开发工具包,Theos是越狱开发工具的首先 ...
- PHP之时间和日期函数
// 时间日期函数 Time <?php date_default_timezone_set('UTC'); // 获取当前时间的时间戳 $time0 = mktime(); $time1 = ...
- html中返回上一页的各种写法【转】
超链接返回上一页代码: <a href="#" onClick="javascript :history.back(-1);">返回上一页</ ...
- BPM配置故事之案例2-文本默认值
Boss感觉方便了很多,然而采购部采购员阿海却还是有点意见,他跑来找小明. 阿海:现在申请都是我在提交,申请人和申请部门能不能不要每次都要填写啊,好麻烦的. 小明:没问题,这个简单. 小明在表单中把申 ...
- Android AndroidRuntime类
AndroidRuntime类是安卓底层很重要的一个类,它负责启动虚拟机以及Java线程,AndroidRuntime类在一个进程中只有一个实例对象保存在全局变量,gCurRuntime中.
- Android中使用ExpandableListView实现微信通讯录界面(完善仿微信APP)
之前的博文<Android中使用ExpandableListView实现好友分组>我简单介绍了使用ExpandableListView实现简单的好友分组功能,今天我们针对之前的所做的仿微信 ...