SQL Server获取下一个编码字符串的实现方案分割和进位
-- 找到到首个数字字符的位置(其所在编码字符串中的位置)
-- 方式1:通过循环获得
--WHILE @tintFistNumPos <= @tintLength
--BEGIN
-- SET @tintCharASCIIValue = ASCII(SUBSTRING(@chvCodeChars, @tintFistNumPos, ));
-- IF @tintCharASCIIValue BETWEEN ASCII('') AND ASCII('')
-- BEGIN
-- BREAK;
-- END -- SET @tintFistNumPos = @tintFistNumPos + ;
--END ---- 分割编码字符串到字母字符串和数字字符串
--SET @chvLetterChars = SUBSTRING(@chvCodeChars, , @tintFistNumPos - );
---- 只有找到数字字时才分割获得数字字符串
--IF @tintFistNumPos <= @tintLength
--BEGIN
-- SET @chvNumChars = SUBSTRING(@chvCodeChars, @tintFistNumPos, @tintLength - @tintFistNumPos + );
--END -- 方法2:通过PATINDEX函数
SET @tintFistNumPos = PATINDEX('%[0-9]%', @chvCodeChars);
IF @tintFistNumPos BETWEEN AND @tintLength -- 编码字符串规则,首字符必须是字母,只有第2个字符才可为数字。
BEGIN
-- 分割编码字符串得到字母字符串
SET @chvLetterChars = SUBSTRING(@chvCodeChars, , @tintFistNumPos - );
-- 分割编码字符串得到数字字符串
SET @chvNumChars = SUBSTRING(@chvCodeChars, @tintFistNumPos, @tintLength - @tintFistNumPos + );
END
ELSE IF @tintFistNumPos = -- 表示该编码字符串全部为字母字符
BEGIN
SET @chvLetterChars = @chvCodeChars;
END
实现方案代码
IF OBJECT_ID(N'dbo.ufn_GetNextCodeChars', 'FN') IS NOT NULL
BEGIN
DROP FUNCTION dbo.ufn_GetNextCodeChars;
END
GO --==================================
-- 功能: 获取下一个编码字符串
-- 说明: 具体实现阐述
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
--==================================
CREATE FUNCTION dbo.ufn_GetNextCodeChars
(
@chvCodeChars VARCHAR() -- 编码字符串,首字符必须以字母A-Z任意一个开始。
) RETURNS VARCHAR()
--$Encode$--
AS
BEGIN;
SET @chvCodeChars = ISNULL(@chvCodeChars, '');
SET @chvCodeChars = UPPER(@chvCodeChars); -- 下一个编码字符串变量
DECLARE @chvNextCodeChars AS VARCHAR();
SET @chvNextCodeChars = ''; -- 编码字符使用的字符字符串变量
DECLARE @chCharStr AS CHAR();
SET @chCharStr = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; DECLARE
@tintLength AS TINYINT,
@tintFistNumPos AS TINYINT;
SELECT
@tintLength = LEN(@chvCodeChars), -- 编码字符串长度变量
@tintFistNumPos = ; -- 首个数字字符所在位置的变量,默认第二个字符是数字字符 DECLARE
@chvLetterChars AS VARCHAR(), -- 字母字符串
@chvNumChars AS VARCHAR(); -- 数字字符串
SELECT
@chvLetterChars = '',
@chvNumChars = ''; -- 字符ASCII值变量
DECLARE @tintCharASCIIValue AS TINYINT;
SET @tintCharASCIIValue = ; -- 编码字符串长度的逻辑检查
IF @tintLength NOT BETWEEN AND
BEGIN
RETURN @chvNextCodeChars;
END -- 首字符是否字母字符的逻辑检查
SET @tintCharASCIIValue = ASCII(SUBSTRING(@chvCodeChars, , ));
IF @tintCharASCIIValue NOT BETWEEN ASCII('A') AND ASCII('Z')
BEGIN
RETURN @chvNextCodeChars;
END -- 所有字符全部为'Z'的逻辑检查
IF @chvCodeChars = REPLICATE('Z', @tintLength)
BEGIN
RETURN @chvNextCodeChars;
END -- 找到到首个数字字符的位置(其所在编码字符串中的位置)
-- 方式1:通过循环获得
--WHILE @tintFistNumPos <= @tintLength
--BEGIN
-- SET @tintCharASCIIValue = ASCII(SUBSTRING(@chvCodeChars, @tintFistNumPos, ));
-- IF @tintCharASCIIValue BETWEEN ASCII('') AND ASCII('')
-- BEGIN
-- BREAK;
-- END -- SET @tintFistNumPos = @tintFistNumPos + ;
--END ---- 分割编码字符串到字母字符串和数字字符串
--SET @chvLetterChars = SUBSTRING(@chvCodeChars, , @tintFistNumPos - );
---- 只有找到数字字时才分割获得数字字符串
--IF @tintFistNumPos <= @tintLength
--BEGIN
-- SET @chvNumChars = SUBSTRING(@chvCodeChars, @tintFistNumPos, @tintLength - @tintFistNumPos + );
--END -- 方法2:通过PATINDEX函数
SET @tintFistNumPos = PATINDEX('%[0-9]%', @chvCodeChars);
IF @tintFistNumPos BETWEEN AND @tintLength -- 编码字符串规则,首字符必须是字母,只有第2个字符才可为数字。
BEGIN
-- 分割编码字符串得到字母字符串
SET @chvLetterChars = SUBSTRING(@chvCodeChars, , @tintFistNumPos - );
-- 分割编码字符串得到数字字符串
SET @chvNumChars = SUBSTRING(@chvCodeChars, @tintFistNumPos, @tintLength - @tintFistNumPos + );
END
ELSE IF @tintFistNumPos = -- 表示该编码字符串全部为字母字符
BEGIN
SET @chvLetterChars = @chvCodeChars;
END -- 字母字符串长度和字母字符串最后一个字母
DECLARE
@tintLetterLength AS TINYINT,
@chLastLetter AS CHAR();
SELECT
@tintLetterLength = LEN(@chvLetterChars),
@chLastLetter = SUBSTRING(@chvLetterChars, @tintLetterLength, ); IF LEN(@chvNumChars) = /*最后一位不为Z或是数字字符时的逻辑处理*/
BEGIN
SET @chvLetterChars = SUBSTRING(@chvLetterChars, , @tintLetterLength - )
+ SUBSTRING(@chCharStr, CHARINDEX(@chLastLetter, @chCharStr, ) + , );
END
ELSE /*数字字符超过1位(最多18位)时逻辑处理*/
BEGIN
-- 声明一个特殊的整数变量,开始为“”后边紧跟数字字符串,在转为整数进行加法运算,如果该结果首字符从1变成了2,则表示前面相邻的字母字符需要递进增加;否则只是数字字符串进行递进增加。
DECLARE @bintNumPlusOne AS BIGINT;
SET @bintNumPlusOne = CAST('' + + @chvNumChars AS BIGINT) + ; IF SUBSTRING(CAST(@bintNumPlusOne AS VARCHAR()), , ) = '' /*数字字符串全部为9*/
BEGIN
IF @chLastLetter = 'Z' /*如果数字字符串相邻前面字母为'Z',则第一个数字变为'A',其余的数字字符串全部变为0*/
BEGIN
SET @chvNumChars = 'A' + REPLICATE('', LEN(@chvNumChars) - );
END
ELSE /*如果数字字符串相邻前面字母不为'Z',则这个字母递进增加,数字字符串全部变为0*/
BEGIN
SET @chvLetterChars = SUBSTRING(@chvLetterChars, , @tintLetterLength - )
+ SUBSTRING(@chCharStr, CHARINDEX(@chLastLetter, @chCharStr, ) + , ); SET @chvNumChars = REPLICATE('', LEN(CAST(@bintNumPlusOne AS VARCHAR())) - );
END
END
ELSE /*数字字符串第一个数字字符不为9,其余的数字字符可全部为9*/
BEGIN
SET @chvNumChars = STUFF(CAST(@bintNumPlusOne AS VARCHAR()), , , '');
END
END -- 将字母字符串和数字字符串一起组装成下一个编码字符串
SET @chvNextCodeChars = @chvLetterChars + @chvNumChars; RETURN @chvNextCodeChars;
END
GO
DECLARE @chvCodeChars AS VARCHAR(); SET @chvCodeChars = 'ZZZZZZZZZZZZZZZZZ99'
SELECT @chvCodeChars AS [当前编码字符串], dbo.ufn_GetNextCodeChars(@chvCodeChars) AS [相邻前面字母为Z且字母进位]; SET @chvCodeChars = 'AAAA99';
SELECT @chvCodeChars AS [当前编码字符串], dbo.ufn_GetNextCodeChars(@chvCodeChars) AS [相邻前面字母不为Z且字母进位]; SET @chvCodeChars = 'ZZZZZZZZZZZZZZZZA99';
SELECT @chvCodeChars AS [当前编码字符串], dbo.ufn_GetNextCodeChars(@chvCodeChars) AS [相邻前面字母不为Z且字母进位]; SET @chvCodeChars = 'ZZZZZZZZZZZZZZZZB00';
SELECT @chvCodeChars AS [当前编码字符串], dbo.ufn_GetNextCodeChars(@chvCodeChars) AS [数字进位]; SET @chvCodeChars = 'ZZZZZZZZZZZZZZZZZA';
SELECT @chvCodeChars AS [当前编码字符串], dbo.ufn_GetNextCodeChars(@chvCodeChars) AS [全为字母且字母进位];
GO

IF OBJECT_ID(N'[dbo].[ufn_GenerateNexCodeChars]', 'FN') IS NOT NULL
BEGIN
DROP FUNCTION [dbo].[ufn_GenerateNexCodeChars];
END
GO CREATE FUNCTION [dbo].[ufn_GenerateNexCodeChars]
(
@chvCodeChars VARCHAR()
) RETURNS VARCHAR()
AS
BEGIN
SET @chvCodeChars = ISNULL(@chvCodeChars, '');
SET @chvCodeChars = UPPER(@chvCodeChars); DECLARE @chvNextCodeChars AS VARCHAR();
SET @chvNextCodeChars = ''; DECLARE
@tintLength AS TINYINT, -- 编码字符串长度
@tintFistNumPos AS TINYINT, -- 编码字符串中第一个数字字符的位置,默认为第2个位置
@chvLetterChars AS VARCHAR(), -- 字母字符串
@chvNumChars AS VARCHAR(), -- 数字字符串
@tintCharASCIIValue AS TINYINT; -- 字符ASCII整数值
SELECT
@tintLength = LEN(@chvCodeChars),
@tintFistNumPos = ,
@chvLetterChars = '',
@chvNumChars = '',
@tintCharASCIIValue = ; -- 编码字符串长度的逻辑检查
IF @tintLength NOT BETWEEN AND
BEGIN
RETURN @chvNextCodeChars;
END -- 所有字符全部为'Z'的逻辑检查
IF @chvCodeChars = REPLICATE('Z', @tintLength)
BEGIN
RETURN @chvNextCodeChars;
END -- 首字符是否字母字符的逻辑检查
SET @tintCharASCIIValue = ASCII(SUBSTRING(@chvCodeChars, , ));
IF @tintCharASCIIValue NOT BETWEEN ASCII('A') AND ASCII('Z')
BEGIN
RETURN @chvNextCodeChars;
END -- 找到到首个数字字符的位置(其所在编码字符串中的位置)
-- 方式1:通过循环获得
--WHILE @tintFistNumPos <= @tintLength
--BEGIN
-- SET @tintCharASCIIValue = ASCII(SUBSTRING(@chvCodeChars, @tintFistNumPos, ));
-- IF @tintCharASCIIValue BETWEEN ASCII('') AND ASCII('')
-- BEGIN
-- BREAK;
-- END -- SET @tintFistNumPos = @tintFistNumPos + ;
--END ---- 分割编码字符串到字母字符串和数字字符串
--SET @chvLetterChars = SUBSTRING(@chvCodeChars, , @tintFistNumPos - );
---- 只有找到数字字符时才分割获得数字字符串
--IF @tintFistNumPos <= @tintLength
--BEGIN
-- SET @chvNumChars = SUBSTRING(@chvCodeChars, @tintFistNumPos, @tintLength - @tintFistNumPos + );
--END -- 方法2:通过PATINDEX函数
SET @tintFistNumPos = PATINDEX('%[0-9]%', @chvCodeChars);
IF @tintFistNumPos BETWEEN AND @tintLength -- 编码字符串规则,首字符必须是字母,只有第2个字符才可为数字。
BEGIN
-- 分割编码字符串得到字母字符串
SET @chvLetterChars = SUBSTRING(@chvCodeChars, , @tintFistNumPos - );
-- 分割编码字符串得到数字字符串
SET @chvNumChars = SUBSTRING(@chvCodeChars, @tintFistNumPos, @tintLength - @tintFistNumPos + );
END
ELSE IF @tintFistNumPos = -- 表示该编码字符串全部为字母字符
BEGIN
SET @chvLetterChars = @chvCodeChars;
END DECLARE
@tintLetterCharsLength AS TINYINT,
@tintNumCharsLength AS TINYINT,
@chLastLetterOfLetterChars AS CHAR();
SELECT
@tintLetterCharsLength = LEN(@chvLetterChars),
@tintNumCharsLength = LEN(@chvNumChars),
@chLastLetterOfLetterChars = SUBSTRING(@chvLetterChars, @tintLetterCharsLength, ); IF @chvNumChars = REPLICATE('', @tintNumCharsLength) -- 当编码字符串需要数字字符串部分进位时,即数字字符串全部为9或空字符串(不是NULL,而是'')
BEGIN
IF @chLastLetterOfLetterChars = 'Z' -- 字母字符串最后一个字母字符是'Z'
BEGIN
SET @chvLetterChars = @chvLetterChars + 'A';
SET @chvNumChars =REPLICATE('', @tintNumCharsLength - );
END
ELSE -- 字母字符串最后一个字母字符不是'Z',则进位该自字母字符
BEGIN
SET @chvLetterChars = SUBSTRING(@chvLetterChars, , @tintLetterCharsLength - )
+ CHAR(ASCII(@chLastLetterOfLetterChars) + );
SET @chvNumChars =REPLICATE('', @tintNumCharsLength);
END
END
ELSE
BEGIN
SET @chvNumChars = CAST(CAST(@chvNumChars AS BIGINT) + AS VARCHAR()) -- 数字部分转换为bigint再递增1再转换为字符串
SET @chvNumChars = REPLICATE('', @tintNumCharsLength - LEN(@chvNumChars))
+ @chvNumChars; -- 数字字符串补充缺0
END SET @chvNextCodeChars =@chvLetterChars+ @chvNumChars; -- 组装下一个编码字符串 RETURN @chvNextCodeChars;
END
GO
测试的T-SQL代码如下:
SELECT dbo.ufn_GenerateNexCodeChars('Z0')
,dbo.ufn_GenerateNexCodeChars('Z9')
,dbo.ufn_GenerateNexCodeChars('ZY')
,dbo.ufn_GenerateNexCodeChars('ZA9');
GO
执行后的查询结果如下:



SQL Server获取下一个编码字符串的实现方案分割和进位的更多相关文章
- SQL Server获取下一个编码字符实现继续重构与增强
我在SQL Server获取下一个编码字符实现的博文中,虽然实现了这个问题,但是感觉维护起来比较麻烦,例如如果调整编码字符串的固定长度,就需要变更三个函数,这样的为何成本确实比较大.面向对象编 ...
- SQL Server获取下一个编码字符实现
周末看到SQL Server 大V潇湘隐者的获取下一个编码字符串问题,本来作为以上博文的回复,也许回复内容长度超过其允许限制,无法提交.鉴于此,特记录SQL Server实现过程,方便自己回顾和查阅. ...
- 【转】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 ...
- 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 ...
- SQLServer数据库之SQL Server 获取本周,本月,本年等时间内记录
本文主要向大家介绍了SQLServer数据库之SQL Server 获取本周,本月,本年等时间内记录,通过具体的内容向大家展现,希望对大家学习SQLServer数据库有所帮助. datediff(we ...
- 第1/24周 SQL Server 如何执行一个查询
大家好,欢迎来到第1周的SQL Server性能调优培训.在我们进入SQL Server性能调优里枯燥难懂的细节内容之前,我想通过讲解SQL Server如何执行一个查询来建立基础.这个部分非常重要, ...
- 第1周 SQL Server 如何执行一个查询
原文:第1周 SQL Server 如何执行一个查询 大家好,欢迎来到第1周的SQL Server性能调优培训.在我们进入SQL Server性能调优里枯燥难懂的细节内容之前,我想通过讲解SQL Se ...
- 使用IP连接SQL SERVER或者配置为连接字符串失败
使用IP连接SQL SERVER或者配置为连接字符串失败 情景一:当在webconfig文件中使用 <add key="ConnectionString" value=& ...
- SQL Server 2008下日志清理方法 2
SQL Server 2008下日志清理方法 (2011-07-14 10:30:45) 转自 http://blog.sina.com.cn/s/blog_4bdd3d0b0100wfvq.html ...
随机推荐
- 在Linux上用自己编译出来的coreclr与donet cli运行asp.net core程序
先在 github 上签出 coreclr 的源代码,运行 ./build.sh 命令进行编译,编译结果在 coreclr/bin/Product/Linux.x64.Debug/ 文件夹中. 接着签 ...
- LUN/PV/VG/LV
存储中的几个概念,参考一些网络资料重新画个图梳理下,如下: LUN:lun是针对存储设备(如磁盘阵列)的逻辑概念,物理上可能就是几块硬盘.那么主机的HBA 卡看到的存储上的存储资源就靠主要两个东西定位 ...
- Web端导出CSV
前端导出文件大部分还是通过服务器端的方式生成文件,然后传递到客户端.但很多情况下当我们导出CSV时并不需要后端参与,甚至没有后端. 做过WebGIS的同学经常会碰到这种场景,用户的兴趣点数据以csv文 ...
- 代码规范、代码复审、PSP
作业三: 代码规范.代码复审.PSP 代码规范 代码规范的重要性 一.规范的代码可以促进团队合作 一个项目大多都是由一个团队来完成,如果没有统一的代码规范,那么每个人的代码必定会风格迥异.且不说会存 ...
- Stealth视频教程学习笔记(第二章)
Stealth视频教程学习笔记(第二章) 本文是对Unity官方视频教程Stealth的学习笔记.在此之前,本人整理了Stealth视频的英文字幕,并放到了优酷上.本文将分别对各个视频进行学习总结,提 ...
- 使用JSSDK集成微信分享遇到的一些坑
h5项目中需要集成微信分享,以实现自定义标题.描述.图片等功能.结果遇到了很多坑. 准备工作 务必详细阅读微信JS-SDK说明文档 需要后端支持 强烈建议下载使用微信web开发者工具 按文档配置好公众 ...
- 快速入门系列--GIT版本控制工具
由于GIT刚刚开始使用不久,经常会在Merge时出现没有change-id的情况,在结合gerrit使用时,经常出现不能提交的情形,使得自己很困扰.最近有次熬夜加班,在代码完成后,由于多人在很短时间内 ...
- .NET 程序启动调试器 .NET 测试代码耗费时间
有些场景的.NET程序,不容易设置断点,可以用下面的方法,在.NET代码中增加启动调试器的代码: if (!Debugger.IsAttached) Debugger.Launch(); .cshar ...
- JS中call、apply、bind使用指南,带部分原理。
为什么需要这些?主要是因为this,来看看this干的好事. box.onclick = function(){ function fn(){ alert(this); } fn();}; 我们原本以 ...
- 找到SQL Server的序列号
有时候希望获取当前机器上安装的SQL Server序列号,但注册表中序列号是经过加密的,因此我写了一个小工具获取当前SQL Server的序列号.程序比较粗糙,没有做错误验证. ...