周末看到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. quick -- 添加按钮

    cc.ui.UIPushButton.new({ normal = "comm_btnGreenBackBack.png", pressed = "comm_btnGre ...

  2. vim 光标按行移动

    记录一下: [ H/M/L ] 注意:这几个命令是大写的. 使用H/M/L这三个键,可以让光标跳到当前窗口的顶部.中间.和底部,停留在第一个非空字符上.H命令和L命令前也可以加一个数字,但数字的含义不 ...

  3. Microsoft Fakes

    http://baike.baidu.com/view/9602275.htm?fr=aladdin http://technet.microsoft.com/zh-cn/magazine/hh549 ...

  4. 完全图解scrollLeft,scrollWidth,clientWidth,offsetWidth 获取相对途径,滚动图片(网上找的,未经试验,但觉得比较好)

    获取元素的位置属性可以通过 HTMLElement.offsetLeft HTMLElement.offsetTop 但是,这两个属性所储存的数值并不是该元素相对整个浏览器画布的绝对位置,而是相对于其 ...

  5. Web service standards: SOAP, REST, OData, and more

    Web service standards: SOAP, REST, OData, and more So far, we've covered the components of a web ser ...

  6. WP-PostViews的安装和设置方法

    wordpress本身并没有文章浏览统计功能,必须借助插件.想要知道自己的文章被多数访客浏览,或者访客对哪些文章或者哪类文章更加有兴趣,这就是文章统计的重要性了.WP-PostViews插件是哥不错的 ...

  7. 自定义android RadioButton View,添加较为灵活的布局处理方式

    android的RadioButton的使用历来都让人比较头疼,如在布局方面,图案.文字无法分别设置padding等,另外,低版本的android RadioGroup不支持换行排列的RadioBut ...

  8. GitHub上排名前100的Android开源库介绍(来自github)

    本项目主要对目前 GitHub 上排名前 100 的 Android 开源库进行简单的介绍,至于排名完全是根据 GitHub 搜索 Java 语言选择 (Best Match) 得到的结果,然后过滤了 ...

  9. 【转】JavaScript中的对象复制(Object Clone)

    JavaScript中并没有直接提供对象复制(Object Clone)的方法.因此下面的代码中改变对象b的时候,也就改变了对象a. a = {k1:1, k2:2, k3:3}; b = a; b. ...

  10. 物料分类账 [COML] PART 2 - 总体流程

    核心流程概要: [1]. 分类账在物料主数据的影响 首先描述下SAP中物料价格的 物料主数据相关的几个点: q价格控制(Price Control): 决定物料计价方式. S 标准价格(Standar ...