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 ...
随机推荐
- 我的ORM之十三 -- 性能参数
我的ORM索引 测试环境 台式机: 主板:映泰Z77 CPU:i5 3470(3.2GHz) 内存:DDR3 1600 8G(单条) 硬盘:创见 SSD 256G ORM从过程上,可以分两个大的部分: ...
- java 多线程(ReadWriteLock)
package com.example; public class App { public static void main(String[] args) { Info info = new Inf ...
- [.net 面向对象编程基础] (12) 面向对象三大特性——继承
[.net 面向对象编程基础] (12) 面向对象三大特性——继承 上节我们说了面向对象的三大特性之一的封装,解决了将对同一对象所能操作的所有信息放在一起,实现统一对外调用,实现了同一对象的复用,降低 ...
- 一天一小段js代码(no.4)
最近在看网上的前端笔试题,借鉴别人的自己来试一下: 题目: 写一段脚本,实现:当页面上任意一个链接被点击的时候,alert出这个链接在页面上的顺序号,如第一个链接则alert(1), 依次类推. 有一 ...
- 如何为编程爱好者设计一款好玩的智能硬件(七)——LCD1602点阵字符型液晶显示模块驱动封装(上)
当前进展: 一.我的构想:如何为编程爱好者设计一款好玩的智能硬件(一)——即插即用.积木化.功能重组的智能硬件模块构想 二.别人家的孩子:如何为编程爱好者设计一款好玩的智能硬件(二)——别人是如何设计 ...
- jQuery为哪般去掉了浏览器检测
由于做HTML5相关的项目,许多前卫时髦的前端技术就需要考虑一下IE是否支持.要是在以前,可以很方便地调用jQuery的jQuery.browser来实现. If(jQuery.browser.msi ...
- Java Spring-Spring与Quartz整合
关于spring mvc.mybatis.maven的整合,请看上一篇文章 Quartz是一个强大的可以在web端执行定时任务的jar包. 本篇文章分为两大不同配置,第一位xml配置,第二位注解配置 ...
- xamarin UWP设置HUD加载功能
使用xamarin开发的时候经常用到加载HUD功能,就是我们常见的一个加载中的动作,Android 下使用 AndHUD , iOS 下使用 BTProgressHUD, 这两个在在 NuGet 上都 ...
- 利用@property实现可控的属性操作
利用@property实现可控的属性操作 Python中没有访问控制符, 不像java之类的 public class Person{ private int x public int getAge( ...
- React(三)组件的生命周期
Component Specs and LifeCycle <div id="app"></div> <script src="bower_ ...