在項目中,大家可能都遇到過,需要把十進制轉換為其他進制的情況,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
)
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、十進制轉換為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進制轉換為十進制
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位數大得多,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。
如何使用
那么我們應該怎么使用這些函數呢,這里舉一個自增36進制字段的表的例子。
首先創建一個表:
CREATE TABLE
xavi
.
tb_Test
(
ID
CHAR
(
10
)
PRIMARY KEY
,
Account
VARCHAR
(
20
),
[Name]
NVARCHAR
(
10
)
)
然后創建一個觸發器:
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條冊數數據:
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
執行看下表里的數據,可以得到如下圖的結果:
從這個結果應該可以觀察到,ID這一列已經是36進制的表示形式了。
擴展用法
有了這個N進制函數,那么我們再生產一些唯一編碼、訂單號等一些編碼時,就可以用更少的位數,表示更大的范圍。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

