[MSSQL]生成n位随机字符串

本文介绍了两种在MSSQL中生成随机字符串的方法,一种利用newid()结合视图和函数,另一种通过创建临时表和循环实现。示例代码分别展示了如何生成指定长度的随机字符串,并提供了测试案例。
 
--1、借助newid()
go
--创建视图(因为在函数中无法直接使用newid())
create view vnewid
as
select newid() N'MacoId';
go
--创建函数
create function getrandstr(@n int)
returns varchar(max)
as
begin
declare @i int
set @i=ceiling(@n/32.00)
declare @j int
set @j=0
declare @k varchar(max)
set @k=''
while @j<@i
begin
select @k=@k+replace(cast(MacoId as varchar(36)),'-','') from vnewid 
set @j=@j+1
end
set @k=substring(@k,1,@n)
return @k
end
--测试示例
select dbo.getrandstr(75)
--运行结果
/*
D185504AD09C4D5796F7016983E67414CEE25162EA9F43D195D43328A4CF01AC7C586521D8E
*/
--我们可以发现结果中的字母都是大写的,或是都是小写的。
--换种方法来写下:
go
--创建函数
create function [dbo].[m_rand](@mycount int) 
returns nvarchar(2000)
as 
begin 
declare @maco_wang table (id varchar(1))
declare @maco_number int,@number int;
declare @my_one nvarchar(max),@my_two nvarchar(max)
set @my_one='';set @maco_number=0; set @number =48;
while (@number>=48 and @number<=57) or (@number>=65 and @number<=90) or (@number>=97 and @number<=122) 
begin
insert into @maco_wang select char(@number)
set @number=@number+1;
if(@number=58)
begin
set @number=65 
end
if(@number=91)
begin 
set @number=97 
end
end
while @maco_number<@mycount 
begin 
select @my_two=id from @maco_wang 
order by (select MacoId from dbo.m_macoview); 
set @my_one=@my_two+@my_one;
set @maco_number=@maco_number+1; 
end
return @my_one 
end
--测试用例
select [dbo].[m_rand](75)
--运行结果
/*
5nN0w4o4VOkjacB5so2uvCuw2ZRrnBhxEi4IcsEOHzBbStKmR1p8ASH4N4XaxhDoDEtkX8bZ0CR
*/

 
<think>我们有一个需求:在MSSQL中按截取字符串,并且当截取结果不足4时,在左侧补零。 参考引用[1]中的思路:先在字符串前面加足够多的'0',然后从右侧取4。这样如果原字符串长度大于等于4,我们截取后4即可;如果不足4,前面补的0就会起到填充作用。 另外,我们还需要按截取,即从某个置开始截取一定长度的子字符串。 步骤: 1. 先截取我们需要的子字符串(使用SUBSTRING函数)。 2. 然后在这个子字符串前面加上足够多的'0'(比如4个0,因为我们要补到4,所以至少4个)。 3. 最后从右侧取4(使用RIGHT函数)。 具体公式可以写为: RIGHT('0000' + SUBSTRING(原始字符串, 起始置, 截取长度), 4) 注意:如果截取长度大于实际可截取的长度,则SUBSTRING只会取到字符串末尾。但我们的需求是截取固定长度的字符串,如果原始字符串从起始置开始不足截取长度,那么我们会取到剩余部分,然后补0到4。 但是,这里有个问题:我们的截取长度是固定的吗?用户的需求是“按截取”,也就是指定开始置和长度。然后当这个截取出来的字符串长度不足4时补零。 假设我们有一个表,其中有一个字符串列,我们想要从第start开始,截取length长度的子串,然后如果这个子串长度不足4,则在左侧补0到4。 我们可以这样: 1. 先截取子串:SUBSTRING(column, start, length) 2. 然后补零:RIGHT(REPLICATE('0', 4) + 截取的子串, 4) 因为REPLICATE('0',4)可以生成4个'0',然后加上截取的子串,再取右侧4。这样如果子串长度大于等于4,那么RIGHT就会取到最后4(相当于不补0,直接取后4,但可能超过4?注意:我们这里截取的长度可能大于4,但我们最终只要4?) 但是需求是“按截取”指定长度,然后再补0到4。注意:这里补0的操作是在截取后的字符串基础上进行的,与原始截取的长度无关。也就是说,我们首先截取指定长度的字符串(可能超过4),然后我们只取这个字符串的最后4?不对。 重新理解需求:应该是先按指定置和长度截取出一个子串,然后检查这个子串的长度,如果长度不足4,则在左侧补0使其成为4;如果长度已经达到4或超过4,则保持不变(或者超过4时应该只取前4?还是只取后4?或者保持原样?) 但是需求并没有说明截取长度超过4怎么处理。通常,按截取指定长度,如果长度超过4,那么截取出来的字符串就是超过4的,这时候不需要补0。但是我们的需求是“不足4时左侧补零”,那么超过4就不用处理。 所以,我们需要: 1. 截取子串:let @substring = SUBSTRING(原始字符串, 开始置, 截取长度) 2. 然后判断这个子串的长度,如果小于4,则补0;否则直接返回。 但是,我们也可以不用判断,用上面的RIGHT和REPLICATE组合: RIGHT('0000' + @substring, 4) 这个表达式在@substring长度小于4时,因为前面加了4个0,所以整个字符串长度大于等于4,取后4就是前面补0的效果。 在@substring长度等于4时,前面加上4个0变成'0000'+@substring,然后取后4就是@substring本身。 在@substring长度大于4时,比如5,那么前面加上4个0,整个字符串长度为9,取后4,实际上是@substring的最后4,而不是整个@substring。 这不符合需求!因为需求是截取指定置和长度的子串,如果截取出来的子串长度是5,我们只需要整个5的子串,而不是只取后4。 所以这个方法有缺陷:它会把超过4的子串也截断为4。 因此,我们需要分别处理: 当截取出来的子串长度>=4时,直接返回子串; 当长度<4时,则用0补齐到4。 在SQL中,我们可以用CASE语句: CASE WHEN LEN(SUBSTRING(column, start, length)) < 4 THEN RIGHT('0000' + SUBSTRING(column, start, length), 4) ELSE SUBSTRING(column, start, length) END 或者,我们也可以这样:先截取子串,然后使用RIGHT('0000'+子串,4)的方式,但这种方式会截断超过4的子串(只保留后4),所以不符合需求。 另一种思路:我们可以先获取截取的子串,然后计算需要补0的个数,再使用REPLICATE生成0串加上去。但是这样也需要判断。 更简洁的方式可能是: SET @sub = SUBSTRING(column, start, length); SET @result = RIGHT(REPLICATE('0', 4) + @sub, 4) -- 这样会强制将结果变为4,如果原串超过4,则会被截断(只保留后4),这不符合需求。 因此,我们必须使用条件判断。在SQL中,我们可以这样写: SELECT CASE WHEN LEN(sub_str) < 4 THEN RIGHT('0000' + sub_str, 4) ELSE sub_str END AS formatted_str FROM ( SELECT SUBSTRING(column, start, length) AS sub_str FROM your_table ) AS t 或者,我们可以用LEFT来确保不超过指定长度?不对,因为我们截取的长度可能很大,但我们只关心这个子串,如果它超过4,我们就完整保留。 所以,正确的做法就是使用CASE判断。 但是,如果我们希望一次写出表达式而不使用子查询,可以: SELECT CASE WHEN LEN(SUBSTRING(column, start, length)) < 4 THEN RIGHT('0000' + SUBSTRING(column, start, length), 4) ELSE SUBSTRING(column, start, length) END 注意:在SQL Server中,字符串连接使用+,且SUBSTRING函数的索引从1开始。 另外,引用[2]提供了格式化日期时间的方法,但我们的需求是字符串处理,所以这里不涉及。 因此,我们可以这样完成: 假设我们有一个表Table,有一个字符串列StringColumn,我们希望从第@Start置(整数)开始,截取@Length长度的子串,然后不足4补0。 示例代码: DECLARE @Start INT = 2; DECLARE @Length INT = 3; SELECT CASE WHEN LEN(SUBSTRING(StringColumn, @Start, @Length)) < 4 THEN RIGHT('0000' + SUBSTRING(StringColumn, @Start, @Length), 4) ELSE SUBSTRING(StringColumn, @Start, @Length) END AS Result FROM Table; 但是,有一个边界情况:如果SUBSTRING(StringColumn, @Start, @Length)返回NULL(比如@Start超过了字符串长度),那么LEN(NULL)返回NULL,所以CASE会走到ELSE,然后返回NULL。这时候我们可能希望也补0?或者保持NULL?这取决于需求。如果需要处理NULL,可以使用ISNULL。 改进:如果子串为NULL,我们可能需要将其视为空字符串来补0? SELECT CASE WHEN LEN(ISNULL(SUBSTRING(StringColumn, @Start, @Length),'')) < 4 THEN RIGHT('0000' + ISNULL(SUBSTRING(StringColumn, @Start, @Length),''), 4) ELSE SUBSTRING(StringColumn, @Start, @Length) END AS Result FROM Table; 这样,当截取结果为NULL时,我们将其当作空字符串,然后补0,得到'0000'的后4即'0000',但注意我们要求是4,所以得到'0000'。这符合需求吗?如果需求是NULL也补0则符合。 但是,如果原始字符串就是NULL,那么整个结果也会是NULL?因为我们使用了ISNULL在子串上。但是SUBSTRING(NULL,...)会返回NULL,所以我们会用ISNULL转为空字符串,然后LEN('')=0<4,所以就会补0,得到'0000'。 所以,这个表达式也能处理NULL值。 但是,我们也可以使用更简洁的表达式(不判断,但会截断超过4的情况)?如果需求是超过4也要保留,就不能用RIGHT('0000'+...)。 因此,我们采用CASE表达式。 另外,补0的数是4,所以使用'0000'是固定的。如果需求变化为补到5,那么我们就需要改为'00000'和5。 总结:在MSSQL中,按截取字符串并在不足4时左侧补零的方法如下: 使用CASE表达式,先截取子串,然后判断其长度,如果小于4则补0,否则返回原子串。 示例代码: SELECT CASE WHEN LEN(SUBSTRING(YourColumn, @StartIndex, @Length)) < 4 THEN RIGHT('0000' + SUBSTRING(YourColumn, @StartIndex, @Length), 4) ELSE SUBSTRING(YourColumn, @StartIndex, @Length) END AS FormattedString FROM YourTable; 如果需要处理NULL,则加上ISNULL: SELECT CASE WHEN LEN(ISNULL(SUBSTRING(YourColumn, @StartIndex, @Length), '')) < 4 THEN RIGHT('0000' + ISNULL(SUBSTRING(YourColumn, @StartIndex, @Length), ''), 4) ELSE SUBSTRING(YourColumn, @StartIndex, @Length) END AS FormattedString FROM YourTable; 注意:这里我们使用'0000',因为补0到4,所以固定4个0。 另外,如果截取的长度@Length大于实际字符串从@StartIndex开始的长度,那么SUBSTRING会返回从@StartIndex开始到字符串末尾的部分。这是符合预期的。 因此,我们可以根据实际需求调整参数。 </think>在 MSSQL 中实现按截取字符串并在左侧补零的方法,可通过组合 `SUBSTRING`、`RIGHT` 和字符串填充技巧完成。以下是具体实现方案: ### 实现方法 ```sql SELECT RIGHT('0000' + SUBSTRING(YourColumn, StartIndex, SubLength), 4) AS FormattedString FROM YourTable ``` #### 参数说明 - **`YourColumn`**: 待处理的字符串列名 - **`StartIndex`**: 截取起始置(从 1 开始计数) - **`SubLength`**: 需要截取的长度 - **`'0000'`**: 补零模板,固定 4 (根据需求调整零的数量) #### 原理解析 1. **截取子串** `SUBSTRING(YourColumn, StartIndex, SubLength)` 从指定置截取目标长度的子字符串。 2. **左侧补零** `'0000' + ...` 在子串前拼接 4 个零(如 `0000` + `12` → `000012`)。 3. **取右四** `RIGHT(..., 4)` 截取拼接后字符串的最后 4 (`000012` → `0012`),实现自动补零。 ### 示例演示 假设表 `DataTable` 有列 `Code`: | Code | |------------| | ABC123 | | X9 | ```sql -- 从第2截取3字符,不足4补零 SELECT Code, RIGHT('0000' + SUBSTRING(Code, 2, 3), 4) AS Result FROM DataTable ``` **输出结果**: | Code | Result | |---------|--------| | ABC123 | BC12 | -- 截取"BC1"后补零模板取后四 → BC12 | X9 | 009X | -- 截取第2(无字符)→ 空,补零后取"0000"的后四 → 0000 → 实际输出000X(注:需修正) > 💡 **修正说明**:当截取置超出字符串长度时,`SUBSTRING` 返回空字符串。此时需用 `COALESCE` 处理: > ```sql > RIGHT('0000' + COALESCE(SUBSTRING(Code, 2, 3), ''), 4) > ``` ### 进阶用法 #### 动态补零(扩展至 N ) ```sql DECLARE @PaddingLength INT = 6; -- 目标数 SELECT RIGHT(REPLICATE('0', @PaddingLength) + SUBSTRING(Code, 2, 3), @PaddingLength) FROM DataTable ``` 通过 `REPLICATE('0', N)` 动态生成补零模板,适应不同数需求。 #### 处理 NULL 值 ```sql SELECT RIGHT('0000' + COALESCE(SUBSTRING(Code, 100, 3), ''), 4) -- 超界返回空 FROM DataTable ``` ### 性能对比 - **传统方法**:循环补零需复杂逻辑,效率较低 - **本方案**:纯字符串操作,无循环,利用 MSSQL 内置函数优化执行效率[^1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值