SQL SERVER中实现十六进制转换为字符的两种方法(三)

两种方法的优缺点:

第一种方法采用自定义函数实现,无须另外写dll,也无须考虑安全性的问题,大家知道sql server中使用sp_oacreate这个存储过程是很危险的,而且执行sp_oacreate需要sysadmin权限,而第一种方法就可以不必考虑这个问题,但第一种方法的缺点是不好控制字符输出格式,而第二种方法很容易控制字符输出的格式

两种方法性能上的比较

我们做如下测试:

新建一Table,如下:

CREATE TABLE Int_To_Hex
 (
  intValue int ,
 strHex varchar(255))

DECLARE @I INT
SET @I=0
WHILE(@I<=10000)
  BEGIN
    INSERT INTO Int_To_Hex(intValue) VALUES(@I)
    SET @I=@I+1
  END

我的电脑配置:

IBMX30  RAM:512M  CPU:P3 1066

第二种方法:

UPDATE Int_To_Hex SET strHex=dbo.fn_GetHexStr(intValue,3)

UPDATE 10001笔,总共耗时13秒,update结果如下:

intValue  strHex
—————————
0           000
1           001
2           002
3           003
4           004
5           005
6           006
7           007
8           008
9           009
10          00A
11          00B
12          00C
13          00D

第一种方法:

UPDATE Int_To_Hex SET strHex=dbo.fn_hexadecimal(intValue)

同样是10001笔资料,共耗时1秒,结果如下:
intValue    strHex
—————————
0           000
1           001
2           002
3           003
4           004
5           005
6           006
7           007
8           008
9           009
10          00A
11          00B
12          00C
13          00D

当然这种测试方法未必是正确的,但从中可以看出二种方法的优点是:

       第一种方法:容易控制输出字符的长度

       第二种方法:性能上有很大的优势

至于采用哪种方法,看各位的需要了:)

相关连接:

SQL SERVER中实现十六进制转换为字符的两种方法(一)

SQL SERVER中实现十六进制转换为字符的两种方法(二)

SQL SERVER中实现十六进制转换为字符的两种方法(二)

第二种方法:

先用VB写一个dll,比如叫intToHex,里面代码如下:

Option Explicit
Public Function IntToHex(intValue As Long, Optional intlength As Long = 2) As String
  IntToHex = Hex$(intValue)
  If Len(IntToHex) < intlength Then
     Dim i As Integer
     For i = 1 To intlength - Len(IntToHex)
         IntToHex = “0″ & IntToHex
     Next
  End If
End Function

其中intValue是要转化的数字,intlength是转化后要保留的字符的长度

将其编译成dll,然后在sql server中执行如下命令注册:

regsvr32 c:\intTohex.dll

然后自己写一个自定义函数,去实现这个功能:

CREATE FUNCTION dbo.fn_GetHexStr ( @intValue int,@paraValue int=4)
 RETURNS VARCHAR(10)
AS
BEGIN
DECLARE @object int
DECLARE @hr int
DECLARE @src varchar(255), @desc varchar(255),@strRet varchar(255)
EXEC @hr = sp_OACreate ‘IntToHex.InToHex’, @object OUT
IF @hr <> 0
BEGIN
   –EXEC sp_OAGetErrorInfo @object, @src OUT, @desc OUT
   –SELECT hr=convert(varbinary(4),@hr),
Source=@src, Description=@desc
    RETURN ‘error’
END
EXEC @hr=sp_OAMethod @object,’IntToHex’,@strRet output,@intValue,@paravalue
IF @hr <> 0
BEGIN
   –EXEC sp_OAGetErrorInfo @object, @src OUT, @desc OUT
   –SELECT hr=convert(varbinary(4),@hr),
Source=@src, Description=@desc
    RETURN ‘error’
END
EXEC sp_OADestroy @object
RETURN @strRet
END

最后在自己的sql语句中这样调用即可:

select dbo.fn_GetHexStr(intValue,3) from Int_To_Hex

相关连接:

SQL SERVER中实现十六进制转换为字符的两种方法(一)

SQL SERVER中实现十六进制转换为字符的两种方法(三)

SQL SERVER中实现十六进制转换为字符的两种方法(一)

前几天同事遇到一客户有这样的需求:

客户给一段范围 比如0000~FFFF ,要求产生一组十六进制序列号 比如逢二进一 就要得到0002,0004,0006。。这一系列序号,最终要把这组序号加上一定的字符型prefix,存储到DB里去,前提是要求所有这一切在SQL后台处理

问我sql中有没有直接将十六进制直接转换为字符的函数?

查了查sql的book online,sql server中对十六进制的表示方法为在十六进制前加上0x,现在的问题就是如何将十六进制的前置符去掉的问题,比如:0xFFFF,要变为FFFF,而sql server中是没有这样的内部函数的,怎么办呢?想了想,大概有两种方法:

1.用sql server2000中的自定义函数去实现

   自定义函数功能强大,应该可以实现这个功能

2.通过sql server中的sp_OACreate等存储过程去调用自己写的dll

   大致想法是这样的:在VB中能很容易实现将十六进制转化为字符,比如用hex$函数即可实现,现在只要自己写一个dll,然后在sql中通过sp_oacreate存储过程去调用即可

对于第一种方法,查了一下资料,发现book online中就有现成的例子可实现这个功能,真是天助我也,看来查资料也是一种很重要的能力:),存储过程如下:

CREATE PROCEDURE sp_hexadecimal
    @binvalue varbinary(255),
    @hexvalue varchar(255) OUTPUT
AS
DECLARE @charvalue varchar(255)
DECLARE @i int
DECLARE @length int
DECLARE @hexstring char(16)
SELECT @charvalue = ”–这个是前缀字符,可定义为自己需要的字符,比如SN,0X
SELECT @i = 1
SELECT @length = DATALENGTH(@binvalue)
SELECT @hexstring = ‘0123456789abcdef’
WHILE (@i <= @length)
BEGIN
DECLARE @tempint int
DECLARE @firstint int
DECLARE @secondint int
SELECT @tempint = CONVERT(int, SUBSTRING(@binvalue,@i,1))
SELECT @firstint = FLOOR(@tempint/16)
SELECT @secondint = @tempint - (@firstint*16)
SELECT @charvalue = @charvalue +
SUBSTRING(@hexstring, @firstint+1, 1) +
SUBSTRING(@hexstring, @secondint+1, 1)
SELECT @i = @i + 1
END
SELECT @hexvalue = @charvalue

GO

使用时只要在sql或存储过程中这样调用即可:

declare @outValue varchar(255)

exec sp_hexadecimal 25,@outvalue output

print @outvalue–这就是你所要的结果

将其改成自定义函数,如下:

CREATE FUNCTION dbo.fn_hexadecimal (@binvalue varbinary(2))
RETURNS varchar(10)
AS 
BEGIN
DECLARE @charvalue varchar(10)
DECLARE @hexstring char(16)
DECLARE @i int
DECLARE @length int
SELECT @charvalue = ”
SELECT @hexstring = ‘0123456789ABCDEF’
SELECT @i=1
SELECT @length=DATALENGTH(@binvalue)
WHILE (@i <= @length)
BEGIN
DECLARE @tempint int
DECLARE @firstint int
DECLARE @secondint int
SELECT @tempint = CONVERT(int, SUBSTRING(@binvalue,@i,1))
SELECT @firstint = FLOOR(@tempint/16)
SELECT @secondint = @tempint - (@firstint*16)
SELECT @charvalue = @charvalue +
SUBSTRING(@hexstring, @firstint+1, 1) +
SUBSTRING(@hexstring, @secondint+1, 1)
SELECT @i = @i + 1
END
RETURN @charvalue
END

注:

1.@binvalue的长度对输出结果很重要,如果你要输出’FFFF’四位的格式,则定义成@binvalue varbinary(2)

2.RETURNS varchar(10),@charvalue–这个宽度不能小于@binvalue宽度的两倍,否则会被截断

使用时跟使用sql内部函数一样

—-待续—-

相关连接:

SQL SERVER中实现十六进制转换为字符的两种方法(二)

SQL SERVER中实现十六进制转换为字符的两种方法(三)

一次奇怪的TNS-00516错误–MSN跟Oracle Listener端口冲突!

今天在自己电脑上手工启动listener时出现如下错误:

监听该对象时出错: (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=bright)(PORT=1521)))
TNS-12546: TNS: 拒绝许可
 TNS-12560: TNS: 协议适配器错误
  TNS-00516: 拒绝许可
   32-bit Windows Error: 13: Permission denied

奇怪!以前都好好的,怎么会报这种错误?难道是权限不够?查看一下当前的用户,没问题呀,是管理员权限,而且也是ORA_DBA群组成员!难道是目录权限不够?一查看也没问题呀!那就奇怪了….难道是端口有冲突?赶紧执行:

 C:\>netstatActive Connections  Proto  Local Address          Foreign Address        State
  TCP    bright:912             bright:1323            ESTABLISHED
  TCP    bright:912             bright:1331            ESTABLISHED
  TCP    bright:912             bright:1332            ESTABLISHED
  TCP    bright:1323            bright:912             ESTABLISHED
  TCP    bright:1331            bright:912             ESTABLISHED
  TCP    bright:1332            bright:912             ESTABLISHED
  TCP   bright:1521 baym-cs331.msgr.hotmail.com:1863  ESTABLISHED
  TCP    bright:2202   ip-32-1-168-192.rev.dyxnet.com:ftp  CLOSE_WAIT
  TCP    bright:2207  ip-32-1-168-192.rev.dyxnet.com:ftp  CLOSE_WAIT
  TCP    bright:2360  ip-32-1-168-192.rev.dyxnet.com:ftp  CLOSE_WAIT
  TCP    bright:2896  baym-gw44.msgr.hotmail.com:http  ESTABLISHED
  TCP    bright:3148  baym-gw27.msgr.hotmail.com:http  ESTABLISHED

果然显示1521端口被占用,而且是被msn占用!害人不浅

将listener端口改成1522,然后重新启动listener,果然起来了!将msn关掉,然后将listener端口改回1521,也起来了,看来就是端口被占用造成的!!

呵呵,真是什么怪事都有,还第一次碰到端口被msn占用而listener无法起来的事情,瑾此为记,以做纪念

  Recent Comments:

    搜索本站

    站点日历

    5月 2012
    « 4    
     123456
    78910111213
    14151617181920
    21222324252627
    28293031  

    订阅本站

    文章分类

    最新日志

    热点文章

    日志存档

    常用标签