在項目中,大家可能都遇到過,需要把十進制轉(zhuǎn)換為其他進制的情況,google上一搜,已經(jīng)有很多2進制、8進制、16進制和十進制的轉(zhuǎn)換方法。但是在一些項目中,這些可能無法滿足要求,可能需要17、18甚至是32、36進制和十進制的轉(zhuǎn)換,那么我們應該怎么辦呢?不可能為每一種進制都去寫一個函數(shù),那樣可不是明智之舉。所以我這里提供一個十進制與N進制之間的互轉(zhuǎn)函數(shù)(N<=32)。
N進制函數(shù)
1、準備工作
在寫N進制函數(shù)之前,需要有一個用于存儲表示N進制字符的基礎表,這里我用一個表函數(shù)表示:
CREATE FUNCTION xavi . fn_NSystemTable () RETURNS @temp TABLE ( id SMALLINT IDENTITY , [Char] CHAR ( 1 ), [Ascii] SMALLINT ) AS BEGIN DECLARE @ignoreAscii TABLE ( [Ascii] SMALLINT ) DECLARE @i INT SET @i = 58 WHILE ( @i <= 64 ) BEGIN INSERT INTO @ignoreAscii VALUES ( @i ) SET @i = @i + 1 END SET @i = 0 WHILE ( @i < 43 ) BEGIN IF NOT EXISTS ( SELECT 1 FROM @ignoreAscii WHERE [Ascii] = @i + 48 ) BEGIN INSERT INTO @temp VALUES ( CHAR ( @i + 48 ), @i + 48 ) END SET @i = @i + 1 END RETURN END
2、十進制轉(zhuǎn)換為N進制
CREATE FUNCTION xavi . fn_DecimalToNSystem ( @bigInt BIGINT , @n TINYINT ) RETURNS VARCHAR ( 100 ) AS BEGIN Declare @result VARCHAR ( 100 ), @mode INT , @remainder INT , @iRet CHAR ( 1 ) SELECT @mode = @bigInt , @result = '' WHILE ( 1 = 1 ) BEGIN IF ( @bigInt = 0 OR @n = 0 OR @n = 1 ) BEGIN SET @result = CONVERT ( VARCHAR ( 100 ), @bigInt ) BREAK END IF ( @mode = 0 ) BEGIN BREAK END SET @remainder = @mode % @n SET @mode = @mode / @n SELECT @iRet = [Char] FROM xavi . fn_NSystemTable () ns WHERE ns . id = @remainder + 1 SET @result = @iRet + @result END RETURN @result END
3、N進制轉(zhuǎn)換為十進制
CREATE FUNCTION xavi . fn_NSystemToDecimal ( @nSys VARCHAR ( 100 ), @n TINYINT ) RETURNS BIGINT AS BEGIN Declare @result int , @iPos int , @iTmp int Select @result = 0 , @iPos = 0 While ( @iPos < Len ( @nSys )) BEGIN SELECT @iTmp = ns . id - 1 FROM xavi . fn_NSystemTable () ns WHERE ns . [Char] = SUBSTRING ( @nSys , LEN ( @nSys ) - @iPos , 1 ) Set @result = @result + @iTmp * POWER ( CAST ( @n AS BIGINT ), cast ( @iPos AS BIGINT )) Set @iPos = @iPos + 1 END RETURN @result END
注意:目前測試下來對于最高進制(36進制),最多支持13位,但是我想這也足夠了,因為36進制所能表示的范圍遠比10進制的13位數(shù)大得多,0<=y<=36 * 36 12 + 36 * 36 11 +......+ 36 * 36 1 + 36。所以一個N進制來說能表示的范圍應該為:0<=y<=N * N x + N * N x-1 +......+ N * N 1 + N。
如何使用
那么我們應該怎么使用這些函數(shù)呢,這里舉一個自增36進制字段的表的例子。
首先創(chuàng)建一個表:
CREATE TABLE xavi . tb_Test ( ID CHAR ( 10 ) PRIMARY KEY , Account VARCHAR ( 20 ), [Name] NVARCHAR ( 10 ) )
然后創(chuàng)建一個觸發(fā)器:
CREATE TRIGGER xavi . tr_TestInsert ON xavi . tb_Test INSTEAD OF INSERT AS SET NOCOUNT ON DECLARE @maxID BIGINT , @n TINYINT , @nSystemChar VARCHAR ( 10 ) SET @n = 36 SELECT @maxID = ISNULL ( MAX ( xavi . fn_NSystemToDecimal ( ID , @n )), 0 ) FROM xavi . tb_Test SET @nSystemChar = xavi . fn_DecimalToNSystem ( @maxID + 1 , @n ) INSERT INTO xavi . tb_Test ( ID , Account , [Name] ) SELECT REPLICATE ( '0' , 10 - LEN ( @nSystemChar )) + @nSystemChar , Account , [Name] FROM INSERTED
接著往這個表里插入100條冊數(shù)數(shù)據(jù):
DECLARE @i INT SET @i = 1 WHILE ( @i <= 100 ) BEGIN INSERT INTO xavi . tb_Test VALUES ( @i ,LEFT( REPLACE ( CONVERT ( VARCHAR ( 100 ), NEWID ()), '-' , '' ), 10 ),LEFT( REPLACE ( CONVERT ( VARCHAR ( 100 ), NEWID ()), '-' , '' ), 10 )) SET @i = @i + 1 END
執(zhí)行看下表里的數(shù)據(jù),可以得到如下圖的結(jié)果:
從這個結(jié)果應該可以觀察到,ID這一列已經(jīng)是36進制的表示形式了。
擴展用法
有了這個N進制函數(shù),那么我們再生產(chǎn)一些唯一編碼、訂單號等一些編碼時,就可以用更少的位數(shù),表示更大的范圍。
更多文章、技術(shù)交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
