SQL Server進位

來源:互聯網
上載者:User

在項目中,大家可能都遇到過,需要把十進位轉換為其他進位的情況,google上一搜,已經有很多2進位、8進位、16進位和十進位的轉換方法。但是在一些項目中,這些可能無法滿足要求,可能需要17、18甚至是32、36進位和十進位的轉換,那麼我們應該怎麼辦呢?不可能為每一種進位都去寫一個函數,那樣可不是明智之舉。所以我這裡提供一個十進位與N進位之間的互轉函數(N<=32)。

N進位函數1、準備工作

在寫N進位函數之前,需要有一個用於儲存表示N進位字元的基礎資料表,這裡我用一個表函數表示:

CREATE FUNCTION xavi.fn_NSystemTable()RETURNS @temp TABLE (id SMALLINT IDENTITY, [Char] CHAR(1),[Ascii] SMALLINT)ASBEGIN    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    RETURNEND
2、十進位轉換為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 @resultEND
3、N進位轉換為十進位
CREATE  FUNCTION xavi.fn_NSystemToDecimal (@nSys VARCHAR(100), @n TINYINT)RETURNS BIGINTASBEGIN    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 @resultEND

注意:目前測試下來對於最高進位(36進位),最多支援13位,但是我想這也足夠了,因為36進位所能表示的範圍遠比10進位的13位元大得多,0<=y<=36 * 3612 + 36 * 3611 +......+ 36 * 361 + 36。所以一個N進位來說能表示的範圍應該為:0<=y<=N * Nx + N * Nx-1 +......+ N * N1 + N。

如何使用

那麼我們應該怎麼使用這些函數呢,這裡舉一個自增36進位欄位的表的例子。

首先建立一個表:

CREATE TABLE xavi.tb_Test(    ID CHAR(10) PRIMARY KEY,    Account VARCHAR(20),    [Name] NVARCHAR(10))

然後建立一個觸發器:

CREATE TRIGGER xavi.tr_TestInsertON xavi.tb_TestINSTEAD OF INSERT ASSET NOCOUNT ONDECLARE @maxID BIGINT,        @n TINYINT,        @nSystemChar VARCHAR(10)SET @n = 36SELECT @maxID = ISNULL(MAX(xavi.fn_NSystemToDecimal(ID,@n)),0) FROM xavi.tb_TestSET @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條冊數資料:

DECLARE @i INTSET @i = 1WHILE(@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 + 1END

執行看下錶裡的資料,可以得到如的結果:

從這個結果應該可以觀察到,ID這一列已經是36進位的表示形式了。

擴充用法

有了這個N進位函數,那麼我們再生產一些唯一編碼、訂單號等一些編碼時,就可以用更少的位元,表示更大的範圍。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.