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 ...
随机推荐
- [.NET领域驱动设计实战系列]专题六:DDD实践案例:网上书店订单功能的实现
一.引言 上一专题已经为网上书店实现了购物车的功能了,在这一专题中,将继续对网上书店案例进行完善,本专题将对网上书店订单功能的实现进行介绍,现在废话不多说了,让我们来一起看看订单功能是如何实现的吧. ...
- Sensor(PROXIMITY)
package com.example.sensor01; import android.hardware.Sensor; import android.hardware.SensorEvent; i ...
- 从分布式一致性谈到CAP理论、BASE理论
问题的提出 在计算机科学领域,分布式一致性是一个相当重要且被广泛探索与论证问题,首先来看三种业务场景. 1.火车站售票 假如说我们的终端用户是一位经常坐火车的旅行家,通常他是去车站的售票处购买车票,然 ...
- C# 关于Try/Catch对系统性能影响的总结
自从开始考虑代码的运行效率和性能以后,写代码考虑的东西越来越多了,比如什么时候应该加try/catch?加太多的try/catch会不会降低性能?今天就来分享一下对try/catch对性能影响的一些看 ...
- C# 版 flvmerge:快速合并多个flv文件
网上的视频很多都是分片的flv文件,怎么把他们合为一体呢?GUI工具就不考虑了,不适合批量执行,不适合在后台运行.有没有命令行工具或库可以实现呢? ffmpeg 提供了一个方法: (1)先把flv文件 ...
- Javascript模块化编程笔记
最近在读阮一峰的博客http://www.ruanyifeng.com/blog/2012/10/javascript_module.html,随手记录一些重要笔记. Javascript模块的雏形 ...
- 使用EntityFramework的烦恼
我有一个应用程序,是实现数据ETL同步的,即把数据从一个db里抽取出来,经过处理后,存储到另一个db里. O/RM采用的是EF db First. 随着项目程序的开发,EF的不足越来越明显. ● 根据 ...
- Java基础之泛型
泛型: (1)为什么会出现泛型? 因为集合存放的数据类型不固定,故往集合里面存放元素时,存在安全隐患, 如果在定义集合时,可以想定义数组一样指定数据类型,那么就可以解决该类安全问题. JDK1.5后出 ...
- Java面向对象思想解决猜拳问题
第一个面向对象的程序: 一个控制台猜拳小游戏: 第一步选择角色: 第二部选择剪刀,石头,布,与电脑进行PK: 第三部选择继续或者选择结束; 结束显示比赛的局数,以及各自赢得的分数: 设计思路 分析问题 ...
- 我心中的核心组件(可插拔的AOP)~调度组件quartz.net
回到目录 quartz.net是一个任务调度组件,它可以灵活的设置你的调试方式,按时间,按日期,按周期都可以很容易的实现,quartz不仅可以用在web中,而且还可以部署在winform,winser ...