我正在尝试使用带有一些限制字母的PL / SQL生成随机字符串,因为我想避免使用O,o,0等字母。我听说使用listagg函数可以实现此任务oracle 11g。但我希望使用Oracle 9i实现这一点,因为我们在我们的环境中使用它。任何建议将不胜感激。
答案 0 :(得分:2)
其中一种方法是创建一个模仿listagg
函数行为的用户定义聚合函数。这是一个例子:
我们的用户定义聚合函数:
SQL> create or replace type stragg as object (
2
3 str varchar2(4000),
4
5 static function ODCIAggregateInitialize(sctx in out stragg)
6 return number,
7
8 member function ODCIAggregateIterate (self in out stragg,
9 value in varchar2 )
10 return number,
11
12 member function ODCIAggregateTerminate (self in stragg ,
13 return_value out varchar2,
14 flags in number )
15 return number,
16
17 member function ODCIAggregateMerge(self in out stragg,
18 ctx2 in stragg )
19 return number
20 )
21 /
Type created
SQL> create or replace type body stragg is
2
3 static function ODCIAggregateInitialize(sctx in out stragg)
4 return number is
5 begin
6 sctx := stragg(null);
7 return ODCIConst.Success;
8 end;
9
10 member function ODCIAggregateIterate(
11 self in out stragg, value in varchar2)
12 return number is
13 begin
14 str := str || value;
15 return ODCIConst.Success;
16 end;
17
18 member function ODCIAggregateTerminate(self in stragg,
19 return_value out varchar2, flags in number) return number is
20 begin
21 return_value := str;
22 return ODCIConst.Success;
23 end;
24
25 member function ODCIAggregateMerge(self in out stragg,
26 ctx2 in stragg) return number is
27 begin
28 str := str || ctx2.str;
29 return ODCIConst.Success;
30 end;
31 end;
32 /
Type body created
SQL> create or replace function str_agg (input varchar2) return varchar2
2 parallel_enable aggregate using stragg;
3 /
Function created
如果您计划使用长度超过4000的字符串,则可以使用CLOB
数据类型而不是varchar2
。现在,您可以创建一个附加函数,使用该str_agg
聚合函数为您生成随机字符串。由于您想从结果字符串中排除某些字符,我认为最好提供一组字符,从中生成所需的字符串。
SQL> create or replace function Str_gen(p_CharSet varchar2, p_length number)
2 return varchar2
3 is
4 l_res_str varchar2(4000);
5 begin
6 select str_agg(symbol)
7 into l_res_str
8 from ( select substr(p_CharSet,
9 dbms_random.value(1, length(p_charset)), 1) as symbol
10 from dual
11 connect by level <= p_length
12 order by dbms_random.value
13 );
14
15 return l_res_str;
16 end;
17 /
Function created
以下是它的工作原理:
SQL> select str_gen('abcdefghijklmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ123456789',11) as res
2 from dual
3 connect by level <= 11
4 /
RES
--------------------------------------------------------------------------------
NBG5jK6G46G
fSrzmyq7ZLE
vdGE1dRXlah
1D2IsI54qzD
PhktBAh5rXu
JtRsarxFNiV
1sUGFpwmypQ
7giwfdV4I7s
I2WMhKzxvc2
NZpngmrq1gM
rFuZ8gSUDgL
11 rows selected
答案 1 :(得分:2)
尝试使用DBMS_RANDOM包生成随机字符串。
Ex:dbms_random.string('x',10)
提供长度为10的大写字母数字字符串。
但你不能排除特定的字符。您必须使用TRANSLATE
或REPLACE
功能删除不需要的字符。
答案 2 :(得分:2)
重复A.B.Cade的回答(它与原版有点太远,无法继续发表评论):
select xmlagg(xmlelement("r", ch)).extract('//text()').getstringval()
from
(
select distinct first_value(ch) over (partition by lower(ch)) as ch
from (
select substr('abcdefghijklmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ123456789',
level, 1) as ch
from dual
connect by level <= 59
order by dbms_random.value
)
where rownum <= dbms_random.value(10,13)
);
内部选择将值中的每个字符放入随机顺序;下一级使用first_value()
和distinct
来选择它首先看到的大写和小写对(a
/ A
),这样你就不会重复甚至忽略大小写;然后限制在前10,11或12(不同)行;最后它使用相同的xmlagg
调用将这些行转换为单个字符串。
答案 3 :(得分:1)
create or replace function str_gen
( len in number)
return varchar2
as
str varchar2(4000);
valid_chars constant varchar2(50) := 'abcdefghijklmnpqrstuvwxyz';
begin
for i in 1..len
loop
str := str || substr( valid_chars, dbms_random.value(1, length(valid_chars)), 1);
end loop;
return str;
end;
/
不直接重复相同的字母
create or replace function str_gen
( len in number)
return varchar2
as
str varchar2(4000);
valid_chars constant varchar2(50) := 'abcdefghijklmnpqrstuvwxyz';
last_char varchar2(1);
new_char varchar2(1);
chars_len NUMBER;
num NUMBER;
begin
chars_len := length(valid_chars);
num := 0;
if len > 0 then
loop
new_char := substr( valid_chars, dbms_random.value(1, chars_len ), 1);
if num = 0 then
str := new_char;
num := num +1;
elsif new_char != last_char
then
str := str || new_char;
num := num +1;
end if;
last_char := new_char;
exit when num = len;
end loop;
end if;
return str;
end;
/
select str_gen(11) from dual;