周末看到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代码如下:
 IF OBJECT_ID(N'dbo.ufn_GetCodeChars', 'TF') IS NOT NULL
BEGIN
DROP FUNCTION dbo.ufn_GetCodeChars;
END
GO --==================================
-- 功能: 获取编码字符表函数
-- 说明: 编码字符只包含0-9和A-Z这两类字符
-- 将以上字符映射到对应十进制数值。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SELECT CodeChar, CodeValue FROM dbo.ufn_GetCodeChars();
--==================================
CREATE FUNCTION dbo.ufn_GetCodeChars
(
) RETURNS @tblCodeChars TABLE (
CodeChar CHAR() NOT NULL,
CodeValue TINYINT NOT NULL
)
--$Encode$--
AS
BEGIN
DECLARE
@intStartIndexID AS TINYINT,
@intEndIndexID AS TINYINT; SELECT
@intStartIndexID = ,
@intEndIndexID = ; -- 初始化0-9数字字符
SELECT
@intStartIndexID = ASCII(''),
@intEndIndexID = ASCII('');
WHILE @intStartIndexID <= @intEndIndexID
BEGIN
INSERT INTO @tblCodeChars (CodeChar, CodeValue)
VALUES (CHAR(@intStartIndexID), ); SET @intStartIndexID = @intStartIndexID + ;
END -- 初始化A-Z字母字符
SELECT
@intStartIndexID = ASCII('A'),
@intEndIndexID = ASCII('Z');
WHILE @intStartIndexID <= @intEndIndexID
BEGIN
INSERT INTO @tblCodeChars (CodeChar, CodeValue)
VALUES (CHAR(@intStartIndexID), ); SET @intStartIndexID = @intStartIndexID + ;
END -- 修改每个编码字符对应的编码值
;WITH tCodeData AS (
SELECT CodeChar, ROW_NUMBER() OVER (ORDER BY CodeChar ASC) AS RowNum
FROM @tblCodeChars
) UPDATE T2
SET T2.CodeValue = T.RowNum -
FROM tCodeData AS T
INNER JOIN @tblCodeChars AS T2
ON T.CodeChar = T2.CodeChar; RETURN;
END
GO
设置编码字符固定长度的标量函数
 
该函数的T-SQL代码如下:
 
 IF OBJECT_ID(N'dbo.ufn_GetCodeCharFixLength', 'FN') IS NOT NULL
BEGIN
DROP FUNCTION dbo.ufn_GetCodeCharFixLength;
END
GO --==================================
-- 功能: 获取编码字符组合的固定长度
-- 说明: 如果转化为int数据类,只能是8位整数,且字符串编码的固定长度只能是8,仅支持5到8位编码字符的组合
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SELECT dbo.ufn_GetCodeCharFixLength();
--==================================
CREATE FUNCTION ufn_GetCodeCharFixLength
(
) RETURNS TINYINT
--$Encode$--
AS
BEGIN
RETURN CAST( AS TINYINT);
END
GO

转换编码字符为整数数值的标量函数

 
该函数的T-SQL代码如下:
 IF OBJECT_ID(N'dbo.ufn_GetCodeIntegerValue', 'FN') IS NOT NULL
BEGIN
DROP FUNCTION dbo.ufn_GetCodeIntegerValue;
END
GO --==================================
-- 功能: 通过编码字符获取其对应的整数数值
-- 说明: 具体实现阐述
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SELECT dbo.ufn_GetCodeIntegerValue('A0000')
--==================================
CREATE FUNCTION dbo.ufn_GetCodeIntegerValue
(
@chCodeChar CHAR() ) RETURNS INT
--$Encode$--
AS
BEGIN
SET @chCodeChar = ISNULL(@chCodeChar, '');
SET @chCodeChar = UPPER(@chCodeChar);
DECLARE @intCodeIntegerValue AS INT;
SET @intCodeIntegerValue = ; DECLARE @tintFixLength AS TINYINT;
SET @tintFixLength =dbo.ufn_GetCodeCharFixLength(); DECLARE @tintLength AS TINYINT;
SET @tintLength = LEN(@chCodeChar); IF @tintLength <= (@tintFixLength - ) OR @tintLength >= (@tintFixLength + )
BEGIN
RETURN @intCodeIntegerValue;
END DECLARE @tblCodeChars TABLE(
CodeChar CHAR() NOT NULL,
CodeValue TINYINT NOT NULL
); INSERT INTO @tblCodeChars (CodeChar, CodeValue)
SELECT CodeChar, CodeValue
FROM dbo.ufn_GetCodeChars(); WHILE @tintLength >=
BEGIN
SELECT @intCodeIntegerValue = @intCodeIntegerValue + CodeValue * POWER(, @tintFixLength - @tintLength)
FROM @tblCodeChars
WHERE CodeChar = SUBSTRING(@chCodeChar, @tintLength, ); SET @tintLength = @tintLength - ;
END RETURN @intCodeIntegerValue;
END
GO
转换为整数数值为编码字符的标量函数
该函数的T-SQL代码如下:
 IF OBJECT_ID(N'dbo.ufn_GetCodeChar', 'FN') IS NOT NULL
BEGIN
DROP FUNCTION dbo.ufn_GetCodeChar;
END
GO --==================================
-- 功能: 通过编码整数值获取对应的编码字符
-- 说明: 具体实现阐述
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
--==================================
CREATE FUNCTION dbo.ufn_GetCodeChar
(
@intCodeIntegerValue INT
) RETURNS CHAR()
--$Encode$--
AS
BEGIN
SET @intCodeIntegerValue = ISNULL(@intCodeIntegerValue, );
DECLARE @chCodeChar AS VARCHAR();
SET @chCodeChar = ''; DECLARE @tintFixLength AS TINYINT;
SET @tintFixLength =dbo.ufn_GetCodeCharFixLength(); IF @intCodeIntegerValue NOT BETWEEN dbo.ufn_GetCodeIntegerValue('A' + REPLICATE('', @tintFixLength - )) AND dbo.ufn_GetCodeIntegerValue(REPLICATE('Z', @tintFixLength))
BEGIN
RETURN @chCodeChar;
END DECLARE @tblCodeChars TABLE(
CodeChar CHAR() NOT NULL,
CodeValue TINYINT NOT NULL
); INSERT INTO @tblCodeChars (CodeChar, CodeValue)
SELECT CodeChar , CodeValue
FROM dbo.ufn_GetCodeChars(); DECLARE @tintPerCodeValue TINYINT;
SET @tintPerCodeValue = ; WHILE @tintFixLength >=
BEGIN
SET @tintPerCodeValue = @intCodeIntegerValue / POWER(, @tintFixLength - ); SELECT TOP @chCodeChar = @chCodeChar + CodeChar, @tintPerCodeValue = CodeValue
FROM @tblCodeChars
WHERE CodeValue <= @tintPerCodeValue
ORDER BY CodeValue DESC; SET @intCodeIntegerValue = @intCodeIntegerValue - @tintPerCodeValue * POWER(, @tintFixLength - ); SET @tintFixLength = @tintFixLength - ;
END RETURN @chCodeChar;
END
GO

测试实现效果

 
测试的T-SQL代码如下:
 DECLARE @chCodeChar AS CHAR();
SET @chCodeChar = 'A0000';
DECLARE @intValue AS INT;
SET @intValue = dbo.ufn_GetCodeIntegerValue(@chCodeChar); SELECT @chCodeChar AS CurrentCodeChar, @intValue AS CurrentCodeIntegerValue, dbo.ufn_GetCodeChar(@intValue + ) AS NextCodeChar;
GO DECLARE @chCodeChar AS CHAR();
SET @chCodeChar = 'ZZZZY';
DECLARE @intValue AS INT;
SET @intValue = dbo.ufn_GetCodeIntegerValue(@chCodeChar); SELECT @chCodeChar AS CurrentCodeChar, @intValue AS CurrentCodeIntegerValue, dbo.ufn_GetCodeChar(@intValue + ) AS NextCodeChar;
GO
执行后的查询结果如下:
 
实现方案的限制
 
    该实现方案只能实现编码字符长度最多为8位的编码字符与整数数值的相互转换。如果要要实现编码字符固定长度更长的(比如编码字符固定长度为6位、7位或8位)功能,必须要修改三个函数,具体的修改处如下图:
 
 
以上图红色矩形框标注的地方,务必要一致才可以的。如果全部更改为6,那就满足编码字符固定长度为6位的实现;也可以修改为7或8,最多只能修改为8。
 
博友如有其他更好的解决方案,也请不吝赐教,万分感谢。
 
 

SQL Server获取下一个编码字符实现的更多相关文章

  1. SQL Server获取下一个编码字符实现继续重构与增强

        我在SQL Server获取下一个编码字符实现的博文中,虽然实现了这个问题,但是感觉维护起来比较麻烦,例如如果调整编码字符串的固定长度,就需要变更三个函数,这样的为何成本确实比较大.面向对象编 ...

  2. SQL Server获取下一个编码字符串的实现方案分割和进位

        我在前一种解决方案SQL Server获取下一个编码字符实现和后一种解决方案SQL Server获取下一个编码字符实现继续重构与增强两篇博文中均提供了一种解决编码的方案,考虑良久对比以上两种方 ...

  3. 【转】sql server 获取每一个类别中值最大的一条数据

    /* 数据如下: name val memo a 2 a2(a的第二个值) a 1 a1--a的第一个值 a 3 a3:a的第三个值 b 1 b1--b的第一个值 b 3 b3:b的第三个值 b 2 ...

  4. sql server 获取每一个类别中值最大的一条数据

    /* 数据如下: name val memo a 2 a2(a的第二个值) a 1 a1--a的第一个值 a 3 a3:a的第三个值 b 1 b1--b的第一个值 b 3 b3:b的第三个值 b 2 ...

  5. 第1/24周 SQL Server 如何执行一个查询

    大家好,欢迎来到第1周的SQL Server性能调优培训.在我们进入SQL Server性能调优里枯燥难懂的细节内容之前,我想通过讲解SQL Server如何执行一个查询来建立基础.这个部分非常重要, ...

  6. 第1周 SQL Server 如何执行一个查询

    原文:第1周 SQL Server 如何执行一个查询 大家好,欢迎来到第1周的SQL Server性能调优培训.在我们进入SQL Server性能调优里枯燥难懂的细节内容之前,我想通过讲解SQL Se ...

  7. SQL Server 2008下日志清理方法 2

    SQL Server 2008下日志清理方法 (2011-07-14 10:30:45) 转自 http://blog.sina.com.cn/s/blog_4bdd3d0b0100wfvq.html ...

  8. SQL Server获取索引创建时间&重建时间&重组时间

    之前写过一篇博客"SQL Server中是否可以准确获取最后一次索引重建的时间?",里面主要讲述了三个问题:我们能否找到索引的创建时间?最后一次索引重建(Index Rebuild ...

  9. SQLServer数据库之SQL Server 获取本周,本月,本年等时间内记录

    本文主要向大家介绍了SQLServer数据库之SQL Server 获取本周,本月,本年等时间内记录,通过具体的内容向大家展现,希望对大家学习SQLServer数据库有所帮助. datediff(we ...

随机推荐

  1. 解决 NDP40-KB2468871不能安装

    新机子 成功装了vs2010,然后装sql2012提示让装vs2012sp1,下载了sp1,装的时候,装到最后一个包NDP40-KB2468871的时候报错了 KB2468871安装失败 错误: Ex ...

  2. Identifier 'Logic.DomainObjectBase._isNew' is not CLS-compliant

    http://stackoverflow.com/questions/1195030/why-is-this-name-not-cls-compliant To get around this err ...

  3. How to import library ?

    Android Studio: Download or git the library. (for example: the library folder named ActionBarSherloc ...

  4. centos 7 /etc/rc.local 开机不执行的问题

    最近发现centos7 的/etc/rc.local不会开机执行,于是认真看了下/etc/rc.local文件内容的就发现了问题的原因了 1 2 3 4 5 6 7 8 9 10 11 #!/bin/ ...

  5. 给The Lab Renderer for Unity中地形添加阴影

    The Lab Renderer for Unity是Valve针对VR在Unity的体验渲染器,提高VR的渲染效率,更多的大家可以查相应资料,在这,说个The Lab Renderer for Un ...

  6. HTML5本地存储之localStorage、sessionStorage

    1.概述 localStorage和sessionStorage统称为Web Storage,它使得网页可以在浏览器端储存数据. sessionStorage保存的数据用于浏览器的一次会话,当会话结束 ...

  7. getRequestURI,getRequestURL的区别

    转自:http://www.cnblogs.com/JemBai/archive/2010/11/10/1873764.html test1.jsp======================= &l ...

  8. asp.net首页设置

    在web.config中设置首页 <configuration> <system.web> <compilation debug="true" tar ...

  9. [转]zetex.lib

    *BAL74 ZETEX Spice Model Last revision 24/8/92*NOTES: FOR RF OPERATION ADD PACKAGE INDUCTANCE 0F 2.5 ...

  10. 牛顿方法(Newton-Raphson Method)

    本博客已经迁往http://www.kemaswill.com/, 博客园这边也会继续更新, 欢迎关注~ 牛顿方法是一种求解等式的非常有效的数值分析方法. 1.  牛顿方法 假设\(x_0\)是等式的 ...