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 ...
随机推荐
- 【WPF】分享自用 白板窗口(空窗口) 控件 BlankWindow,基于WindowChrome。
一.背景 吃产品的亏,上设计的当,最后死在变化上. 现在的产品和设计都喜欢在窗口上做一些事,比如让Title做很多事,好像跟人家用一样的窗口很Low似的,好像真的挺Low的. 所以,还不如弄一个黑板似 ...
- 在asp.net WebAPI 中 使用Forms认证和ModelValidata(模型验证)
一.Forms认证 1.在webapi项目中启用Forms认证 Why:为什么要在WebAPI中使用Forms认证?因为其它项目使用的是Forms认证. What:什么是Forms认证?它在WebAP ...
- Programming Entity Framework CodeFirst--表关系约定
表之间的关系分为一对多,多对多,一对一三种,实质就是对外键进行配置. 一.一对多 1. Required Destination包含Lodging>的集合. public class Desti ...
- 【吉光片羽】js横向滚动与浮动导航
1.横向滚动,这个方法是见过最简洁的了. #demo { background: #FFF; overflow: hidden; border: 1px dashed #CCC; width: 117 ...
- printf背后的故事
printf背后的故事 说起编程语言,C语言大家再熟悉不过.说起最简单的代码,Helloworld更是众所周知.一条简单的printf语句便可以完成这个简单的功能,可是printf背后到底做了什么事情 ...
- [翻译].NET随机数
原文链接:http://csharpindepth.com/Articles/Chapter12/Random.aspx 随机数 当你在Stack Overflow上看到看到某个问题标题当中有“随 ...
- 数据库MySQL开篇
作为一名前端,后天方面的知识虽说不一定要精通后台但是对后台方面的知识有一定了解是非常必要的. 今天先说一些概念方面的,因本人才疏学浅,对于数据库这方面的自学相当于摸着石头过河,有什么写的不对的地方,希 ...
- Atititi tesseract使用总结
Atititi tesseract使用总结 消除bug,优化,重新发布.当前版本为3.02 项目下载地址为:http://code.google.com/p/tesseract-ocr. Window ...
- html5视频全频播放
html5视频全频播放 旋转90度 对video进行缩放 修正position 效果还凑合 代码 $(media).rotate({ // angle: 90, duration: 100, anim ...
- scrollview 中嵌套多个listview的最好解决办法
在scrollview中嵌套多个listview的显示问题. 只需要调用如下的方法传入listview和adapter数据即可. /** * 动态设置ListView组建的高度 */ public s ...