SQL Server獲取下一個編碼字符實現


    周末看到SQL Server 大V瀟湘隱者獲取下一個編碼字符串問題,本來作為以上博文的回復,也許回復內容長度超過其允許限制,無法提交。鑒於此,特記錄SQL Server實現過程,方便自己回顧和查閱。


    我簡單總結編碼字符的規則如下:
1、5位長度,只能包含0-9數字字符和A-Z(大寫)字母字符,且第一位從A開始,最小編碼字符為A0000,最大編碼字符為ZZZZZ。
2、編碼字符是遞進增加的,例如:首個編碼是A0000,下一個是A0001,直到A9999,其下一個是B0000,直到B9999,其下一個是C0000,……,如果編碼是ZB999,下一個是ZC000,……,直到ZZZZZ。
具體的規則請參看 獲取下一個編碼字符串問題
 
    從規則入手分析規則2,編碼字符是遞進增加,間隔為1,也就是一個連續的整數序列,開始整數值和結束整數值固定的。如果編碼字符和整數數值之間實現某種相互轉換,那么這個問題也就解決啦。
 
    從規則1來看,需要定義硬編碼實現0-9數字字符和A-Z(大寫)字母字符與相應10進制整數值的對應;還需要實現將一個編碼字符轉化為整數數值;當然也需要實現將一個整數數值轉化為一個編碼字符;目前僅是滿足5位長度,如果以后擴充到6位,更多位數的需求產生了呢,這個需要設置編碼字符的統一固定長度。以上四個方面我分別定義其對應的函數來實現:硬編碼字符映射表值函數、轉換編碼字符為整數數值的標量函數、轉換整數數值為編碼字符的標量函數和設置編碼字符固定長度的標量函數。
 
 
  硬編碼字符映射表值函數
 
該函數的T-SQL代碼如下:
 1 IF OBJECT_ID(N'dbo.ufn_GetCodeChars', 'TF') IS NOT NULL
 2 BEGIN
 3     DROP FUNCTION dbo.ufn_GetCodeChars;
 4 END
 5 GO
 6  
 7 --==================================
 8 -- 功能: 獲取編碼字符表函數
 9 -- 說明: 編碼字符只包含0-9和A-Z這兩類字符
10 --       將以上字符映射到對應十進制數值。
11 -- 作者: XXX
12 -- 創建: yyyy-MM-dd
13 -- 修改: yyyy-MM-dd XXX 修改內容描述
14 -- 調用: SELECT CodeChar, CodeValue FROM dbo.ufn_GetCodeChars();
15 --==================================
16 CREATE FUNCTION dbo.ufn_GetCodeChars
17 (
18 ) RETURNS @tblCodeChars TABLE (
19     CodeChar CHAR(1) NOT NULL,
20     CodeValue TINYINT NOT NULL
21 )
22     --$Encode$--
23 AS
24 BEGIN
25     DECLARE
26         @intStartIndexID AS TINYINT,
27         @intEndIndexID AS TINYINT;
28  
29     SELECT
30         @intStartIndexID = 0,
31         @intEndIndexID = 0;
32  
33     -- 初始化0-9數字字符
34     SELECT
35         @intStartIndexID = ASCII('0'),
36         @intEndIndexID = ASCII('9');
37     WHILE @intStartIndexID <= @intEndIndexID
38     BEGIN
39         INSERT INTO @tblCodeChars (CodeChar, CodeValue)
40         VALUES (CHAR(@intStartIndexID), 0);
41  
42         SET @intStartIndexID = @intStartIndexID + 1;         
43     END
44  
45     -- 初始化A-Z字母字符
46     SELECT
47         @intStartIndexID = ASCII('A'),
48         @intEndIndexID = ASCII('Z');
49     WHILE @intStartIndexID <= @intEndIndexID
50     BEGIN
51         INSERT INTO @tblCodeChars (CodeChar, CodeValue)
52         VALUES (CHAR(@intStartIndexID), 0);
53  
54         SET @intStartIndexID = @intStartIndexID + 1;         
55     END
56  
57     -- 修改每個編碼字符對應的編碼值
58     ;WITH tCodeData AS (
59         SELECT CodeChar, ROW_NUMBER() OVER (ORDER BY CodeChar ASC) AS RowNum
60         FROM @tblCodeChars
61     )
62  
63     UPDATE T2
64     SET T2.CodeValue = T.RowNum - 1
65     FROM tCodeData AS T
66         INNER JOIN @tblCodeChars AS T2
67             ON T.CodeChar = T2.CodeChar;
68  
69     RETURN;
70 END
71 GO

 

設置編碼字符固定長度的標量函數
 
該函數的T-SQL代碼如下:
 
 1 IF OBJECT_ID(N'dbo.ufn_GetCodeCharFixLength', 'FN') IS NOT NULL
 2 BEGIN
 3     DROP FUNCTION dbo.ufn_GetCodeCharFixLength;
 4 END
 5 GO
 6  
 7 --==================================
 8 -- 功能: 獲取編碼字符組合的固定長度
 9 -- 說明: 如果轉化為int數據類,只能是8位整數,且字符串編碼的固定長度只能是8,僅支持5到8位編碼字符的組合
10 -- 作者: XXX
11 -- 創建: yyyy-MM-dd
12 -- 修改: yyyy-MM-dd XXX 修改內容描述
13 -- 調用: SELECT dbo.ufn_GetCodeCharFixLength();
14 --==================================
15 CREATE FUNCTION ufn_GetCodeCharFixLength
16 (
17 ) RETURNS TINYINT
18     --$Encode$--
19 AS
20 BEGIN
21     RETURN CAST(5 AS TINYINT);
22 END
23 GO

 

轉換編碼字符為整數數值的標量函數

 
該函數的T-SQL代碼如下:
 1 IF OBJECT_ID(N'dbo.ufn_GetCodeIntegerValue', 'FN') IS NOT NULL
 2 BEGIN
 3     DROP FUNCTION dbo.ufn_GetCodeIntegerValue;
 4 END
 5 GO
 6  
 7 --==================================
 8 -- 功能: 通過編碼字符獲取其對應的整數數值
 9 -- 說明: 具體實現闡述
10 -- 作者: XXX
11 -- 創建: yyyy-MM-dd
12 -- 修改: yyyy-MM-dd XXX 修改內容描述
13 -- 調用: SELECT dbo.ufn_GetCodeIntegerValue('A0000')
14 --==================================
15 CREATE FUNCTION dbo.ufn_GetCodeIntegerValue
16 (
17     @chCodeChar CHAR(5)
18  
19 ) RETURNS INT
20     --$Encode$--
21 AS
22 BEGIN
23     SET @chCodeChar = ISNULL(@chCodeChar, '');    
24     SET @chCodeChar = UPPER(@chCodeChar);
25     DECLARE @intCodeIntegerValue AS INT;
26     SET @intCodeIntegerValue = 0;
27  
28     DECLARE @tintFixLength AS TINYINT;
29     SET @tintFixLength =dbo.ufn_GetCodeCharFixLength();
30  
31     DECLARE @tintLength AS TINYINT;
32     SET @tintLength = LEN(@chCodeChar);
33  
34     IF @tintLength <= (@tintFixLength - 1) OR @tintLength >= (@tintFixLength + 1)
35     BEGIN
36         RETURN @intCodeIntegerValue;
37     END
38  
39     DECLARE @tblCodeChars TABLE(
40         CodeChar CHAR(1) NOT NULL,
41         CodeValue TINYINT NOT NULL
42     );
43  
44     INSERT INTO  @tblCodeChars (CodeChar, CodeValue)
45     SELECT CodeChar, CodeValue
46     FROM dbo.ufn_GetCodeChars();
47  
48     WHILE @tintLength >= 1
49     BEGIN    
50         SELECT @intCodeIntegerValue = @intCodeIntegerValue + CodeValue * POWER(10, @tintFixLength - @tintLength)
51         FROM @tblCodeChars
52         WHERE CodeChar = SUBSTRING(@chCodeChar, @tintLength, 1);
53  
54         SET @tintLength = @tintLength - 1;        
55     END
56  
57     RETURN @intCodeIntegerValue;
58 END
59 GO

 

轉換為整數數值為編碼字符的標量函數
該函數的T-SQL代碼如下:
 1 IF OBJECT_ID(N'dbo.ufn_GetCodeChar', 'FN') IS NOT NULL
 2 BEGIN
 3     DROP FUNCTION dbo.ufn_GetCodeChar;
 4 END
 5 GO
 6  
 7 --==================================
 8 -- 功能: 通過編碼整數值獲取對應的編碼字符
 9 -- 說明: 具體實現闡述 
10 -- 作者: XXX
11 -- 創建: yyyy-MM-dd
12 -- 修改: yyyy-MM-dd XXX 修改內容描述
13 --==================================
14 CREATE FUNCTION dbo.ufn_GetCodeChar
15 (
16     @intCodeIntegerValue INT
17 ) RETURNS CHAR(5)
18     --$Encode$--
19 AS
20 BEGIN
21     SET @intCodeIntegerValue = ISNULL(@intCodeIntegerValue, 0);
22     DECLARE @chCodeChar AS VARCHAR(9);
23     SET @chCodeChar = '';
24  
25     DECLARE @tintFixLength AS TINYINT;
26     SET @tintFixLength =dbo.ufn_GetCodeCharFixLength();
27  
28     IF @intCodeIntegerValue NOT BETWEEN dbo.ufn_GetCodeIntegerValue('A' + REPLICATE('0', @tintFixLength - 1)) AND dbo.ufn_GetCodeIntegerValue(REPLICATE('Z', @tintFixLength))
29     BEGIN
30         RETURN @chCodeChar;
31     END
32  
33     DECLARE @tblCodeChars TABLE(
34         CodeChar CHAR(1) NOT NULL,
35         CodeValue TINYINT NOT NULL
36     );
37  
38     INSERT INTO  @tblCodeChars (CodeChar, CodeValue)
39     SELECT CodeChar , CodeValue
40     FROM dbo.ufn_GetCodeChars();
41  
42     DECLARE @tintPerCodeValue TINYINT;
43     SET @tintPerCodeValue = 0;
44  
45     WHILE @tintFixLength >= 1
46     BEGIN        
47         SET @tintPerCodeValue =  @intCodeIntegerValue / POWER(10, @tintFixLength - 1);
48  
49         SELECT TOP 1 @chCodeChar = @chCodeChar + CodeChar, @tintPerCodeValue = CodeValue 
50         FROM @tblCodeChars
51         WHERE CodeValue <= @tintPerCodeValue
52         ORDER BY CodeValue DESC;
53  
54         SET @intCodeIntegerValue = @intCodeIntegerValue - @tintPerCodeValue * POWER(10, @tintFixLength - 1);
55  
56         SET @tintFixLength = @tintFixLength - 1;
57     END
58  
59     RETURN @chCodeChar;
60 END
61 GO
62  

 

測試實現效果

 
測試的T-SQL代碼如下:
 1 DECLARE @chCodeChar AS CHAR(8);
 2 SET @chCodeChar = 'A0000';
 3 DECLARE @intValue AS INT;
 4 SET @intValue = dbo.ufn_GetCodeIntegerValue(@chCodeChar);
 5  
 6 SELECT @chCodeChar AS CurrentCodeChar, @intValue AS CurrentCodeIntegerValue, dbo.ufn_GetCodeChar(@intValue + 1) AS NextCodeChar;
 7 GO
 8  
 9 DECLARE @chCodeChar AS CHAR(8);
10 SET @chCodeChar = 'ZZZZY';
11 DECLARE @intValue AS INT;
12 SET @intValue = dbo.ufn_GetCodeIntegerValue(@chCodeChar);
13  
14 SELECT @chCodeChar AS CurrentCodeChar, @intValue AS CurrentCodeIntegerValue, dbo.ufn_GetCodeChar(@intValue + 1) AS NextCodeChar;
15 GO

 

執行后的查詢結果如下:
 
實現方案的限制
 
    該實現方案只能實現編碼字符長度最多為8位的編碼字符與整數數值的相互轉換。如果要要實現編碼字符固定長度更長的(比如編碼字符固定長度為6位、7位或8位)功能,必須要修改三個函數,具體的修改處如下圖:
 
 
以上圖紅色矩形框標注的地方,務必要一致才可以的。如果全部更改為6,那就滿足編碼字符固定長度為6位的實現;也可以修改為7或8,最多只能修改為8。
 
博友如有其他更好的解決方案,也請不吝賜教,萬分感謝。
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM