T-SQL 批量生成指定范围和长度的随机无重复字符串

MrDotWalker 2011-09-22 01:49:57
说得直白点就是生成一堆Primary Key,但是按照指定长度指定范围。比如说我字符串的字符只能在字符池
@CHARPOOL = '0123456789abcdefghijklmnopqrstuvwxyz'里面取,当然每个串的字符是可以重复的,只是字符串保持唯一就可以了,我也看过用newid()来做的,但是不能指定长度,因为newid()用cast或者convert转化最少也要36的长度,若用
-------------------------------------------------------------------------------------------------------
declare @something varchar(8)
set @something = CONVERT(varchar(36), @myid)
-------------------------------------------------------------------------------------------------------
类似的语句,虽然看起来只有那么8字符长,实际上成了截取一个36位字符的前8位,那么久并不能保持它的唯一性了,所以我想问的是有没有一种方法可以批量生成真正的Primary Key?
先谢谢大家了,有点急,洗完高手踊跃回答,谢谢了。。
...全文
871 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
MrDotWalker 2011-09-22
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 mycodeis0000 的回复:]

建议楼主再建一个表
如t_PrimaryKey(PrimaryKey varchar(8))
保存已有的主键,每次随即生成的主键都与之比较 这样至少不会出现重复主键
[/Quote]你说的是有道理,但是要是插入数据多的话是不是就很耗时间呢?有没有更好的办法?谢谢。。
MrDotWalker 2011-09-22
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 long_hardworking 的回复:]

引用 15 楼 jyh070207 的回复:

引用 14 楼 long_hardworking 的回复:
引用 13 楼 jyh070207 的回复:

用户定义函数主体中不允许有不确定函数,比如NEWID,RAND,改用存储过程.

存储过程怎么做,给个完整的吧,以及调用方法,谢谢。。

根据你的函数改的,调用方法也要改一下
create procedure dbo.Ge……
[/Quote]你说的是有道理,但是要是插入数据多的话是不是就很耗时间呢?有没有更好的办法?谢谢。。
mycodeis0000 2011-09-22
  • 打赏
  • 举报
回复
建议楼主再建一个表
如t_PrimaryKey(PrimaryKey varchar(8))
保存已有的主键,每次随即生成的主键都与之比较 这样至少不会出现重复主键
MrDotWalker 2011-09-22
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 jyh070207 的回复:]

引用 14 楼 long_hardworking 的回复:
引用 13 楼 jyh070207 的回复:

用户定义函数主体中不允许有不确定函数,比如NEWID,RAND,改用存储过程.

存储过程怎么做,给个完整的吧,以及调用方法,谢谢。。

根据你的函数改的,调用方法也要改一下
create procedure dbo.GetRandStr
(@Count int,@no ……
[/Quote]
嗯,真的很谢谢了,呵呵。。
jyh070207 2011-09-22
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 long_hardworking 的回复:]
引用 13 楼 jyh070207 的回复:

用户定义函数主体中不允许有不确定函数,比如NEWID,RAND,改用存储过程.

存储过程怎么做,给个完整的吧,以及调用方法,谢谢。。
[/Quote]
根据你的函数改的,调用方法也要改一下
create procedure dbo.GetRandStr
(@Count int,@no varchar(8) output)
AS
BEGIN
DECLARE @RANDOMSTR VARCHAR(100), @CHARPOOL VARCHAR(36), @ss varchar
DECLARE @I INTEGER, @counter INTEGER
SET @CHARPOOL = '0123456789abcdefghijklmnopqrstuvwxyz'
SET @I = 1
SET @RANDOMSTR = ''
WHILE @I <= @Count
BEGIN
HERE:
SET @counter = CAST(RAND() * 100 / 2.75 AS INTEGER)
IF @counter < 1 GOTO HERE
SET @RANDOMSTR = @RANDOMSTR + SUBSTRING(@CHARPOOL, @counter ,1)
SET @I = @I + 1
END
set @no = left(@RANDOMSTR,isnull(@Count,8))
return
END
GO

DECLARE @something VARCHAR(12)
exec GetRandStr 8,@something output
PRINT @something
GO
MrDotWalker 2011-09-22
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 jyh070207 的回复:]

用户定义函数主体中不允许有不确定函数,比如NEWID,RAND,改用存储过程.
[/Quote]
存储过程怎么做,给个完整的吧,以及调用方法,谢谢。。
jyh070207 2011-09-22
  • 打赏
  • 举报
回复
用户定义函数主体中不允许有不确定函数,比如NEWID,RAND,改用存储过程.
MrDotWalker 2011-09-22
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 qianjin036a 的回复:]

为什么不用自增列呢?那可是标准的做主键的方法啊!
[/Quote]
但是我要的是字符串而非数字串,自增列可以实现不?谢谢。。
-晴天 2011-09-22
  • 打赏
  • 举报
回复
不管什么随机数,都有可能重复.但自增列,决不会重复.
-晴天 2011-09-22
  • 打赏
  • 举报
回复
为什么不用自增列呢?那可是标准的做主键的方法啊!
MrDotWalker 2011-09-22
  • 打赏
  • 举报
回复

USE test
GO
CREATE FUNCTION dbo.GetRandStr
(@Count INTEGER = 8)
RETURNS VARCHAR
AS
BEGIN
DECLARE @RANDOMSTR VARCHAR(100), @CHARPOOL VARCHAR(36), @ss varchar
DECLARE @I INTEGER, @counter INTEGER
SET @CHARPOOL = '0123456789abcdefghijklmnopqrstuvwxyz'
SET @I = 1
SET @RANDOMSTR = ''
WHILE @I <= @Count
BEGIN
HERE:
SET @counter = CAST(RAND() * 100 / 2.75 AS INTEGER)
IF @counter < 1 GOTO HERE
SET @RANDOMSTR = @RANDOMSTR + SUBSTRING(@CHARPOOL, @counter ,1)
SET @I = @I + 1
END
RETURN @RANDOMSTR
END
GO
DECLARE @something VARCHAR(12)
SET @something = dbo.GetRandStr(12)
PRINT @something
GO
--DROP FUNCTION dbo.GetRandStr
MrDotWalker 2011-09-22
  • 打赏
  • 举报
回复

USE test
GO
CREATE FUNCTION dbo.GetRandStr
(@Count INTEGER = 8)
RETURNS VARCHAR
AS
BEGIN
DECLARE @RANDOMSTR VARCHAR(100), @CHARPOOL VARCHAR(36), @ss varchar
DECLARE @I INTEGER, @counter INTEGER
SET @CHARPOOL = '0123456789abcdefghijklmnopqrstuvwxyz'
SET @I = 1
SET @RANDOMSTR = ''
WHILE @I <= @Count
BEGIN
HERE:
SET @counter = CAST(RAND() * 100 / 2.75 AS INTEGER)
IF @counter < 1 GOTO HERE
SET @RANDOMSTR = @RANDOMSTR + SUBSTRING(@CHARPOOL, @counter ,1)
SET @I = @I + 1
END
RETURN @RANDOMSTR
END
GO
DECLARE @something VARCHAR(12)
SET @something = dbo.GetRandStr(12)
PRINT @something
GO
--DROP FUNCTION dbo.GetRandStr
--这个函数这样调用不行吗?总是出现“在函数内的 'newid' 中对带副作用的或依赖于时间的运算符的使用无效。”的错误!怎么办。。
MrDotWalker 2011-09-22
  • 打赏
  • 举报
回复
嗯,我先再想想办法,各位要是有更好的办法,甩过来,谢谢。。
净灵 2011-09-22
  • 打赏
  • 举报
回复
有些字符串取值指令还是挺实用的,现在我也记不起来了,查查相关手册,可能有
Mr_Nice 2011-09-22
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 long_hardworking 的回复:]

引用 2 楼 orchidcat 的回复:

自己做随机,也无非是使用了newid()的结果,然后通过计算获得。

LZ是否可以考虑直接使用newid(),把生成随机数的烦恼交给SQL Server去搞定???

直接用newid()无非是把它转化成36位的字符,但我若想的到的唯一码是8位或者其它,我该结合什么来用啊?谢谢。。
[/Quote]


LZ 参考http://zh-cn.w3support.net/index.php?db=so&id=904920
http://zh.wikipedia.org/wiki/%E5%85%A8%E5%B1%80%E5%94%AF%E4%B8%80%E6%A0%87%E8%AF%86%E7%AC%A6
GUID 实质上是一个128位长的二进制整数。

newid的算法在考虑独立性方面有更好的特性。如果是作为主键使用。建议还是使用newid,虽然它占用空间较大。


如果LZ的需求是穷尽8位某字符的组合的话,可以用cross join 等处理获取。


净灵 2011-09-22
  • 打赏
  • 举报
回复
用变量赋值看看,有些变量设定指定长度就是取前几位,或是要适当位移,你自己再想想办法
MrDotWalker 2011-09-22
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 orchidcat 的回复:]

自己做随机,也无非是使用了newid()的结果,然后通过计算获得。

LZ是否可以考虑直接使用newid(),把生成随机数的烦恼交给SQL Server去搞定???
[/Quote]
直接用newid()无非是把它转化成36位的字符,但我若想的到的唯一码是8位或者其它,我该结合什么来用啊?谢谢。。
Mr_Nice 2011-09-22
  • 打赏
  • 举报
回复
自己做随机,也无非是使用了newid()的结果,然后通过计算获得。

LZ是否可以考虑直接使用newid(),把生成随机数的烦恼交给SQL Server去搞定???
MrDotWalker 2011-09-22
  • 打赏
  • 举报
回复
其中set @myid = newid(); --不好意思,漏了。。

34,836

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧