我的问题是关于PL SQL序列,该序列需要在以值开头和最大值之间给出随机值。我们可以做到吗?
答案 0 :(得分:2)
好的,请使用DBMS_RANDOM.VALUE
。这是概念的简要证明:
set serveroutput on
declare
x number;
begin
x := dbms_random.value(3, 9);
dbms_output.put_line(x);
end;
/
7.77738390408807611656323701045019115674
PL/SQL procedure successfully completed.
您可能需要查看整个软件包:https://docs.oracle.com/database/121/ARPLS/d_random.htm#ARPLS040
答案 1 :(得分:0)
这是一种可能有用的替代方法。它不是很随机,因为它基本上所做的只是获取一个连续的序列号并弄乱数字。为了避免类似“ 100”和“ 1000”的情况都返回数字“ 1”,我在起始值上添加了一个随机数字1-9。
之所以要使用正整数,是为了避免在返回值时出现重复/冲突,因为随机函数会发生这种情况。
您当然可以使用DBMS_RANDOM方法,并针对目标表建立检查。列值以检查该值是否尚未使用。
所以,这是我快速又肮脏的随机解决方案:
我还没有对它进行彻底的测试。
首先创建一个正常序列:
CREATE SEQUENCE the_seq START WITH 10000;
现在该函数可以随机加扰从序列返回的数字:
CREATE OR REPLACE FUNCTION get_seq_val RETURN NUMBER IS
l_seq_val VARCHAR2(50);
l_ret_val VARCHAR2(50);
l_seq_len NUMBER;
l_digit NUMBER;
BEGIN
SELECT RTRIM(LTRIM(TO_CHAR(the_seq.NEXTVAL))) INTO l_seq_val FROM dual;
DBMS_OUTPUT.PUT ( 'Seq: ' || l_seq_val );
l_seq_len := LENGTH(l_seq_val);
l_ret_val := TRUNC(dbms_random.value(1,9)); -- Avoid having 0 as leading digit below
DBMS_OUTPUT.PUT ( ' Ret: ' || l_ret_val );
FOR i IN 1 .. l_seq_len LOOP
l_digit := TRUNC(dbms_random.value(1, LENGTH(l_seq_val)));
l_ret_val := l_ret_val || SUBSTR(l_seq_val, l_digit, 1);
l_seq_val := REGEXP_REPLACE(l_seq_val, '(?<=^.{' || l_digit || '})', '' );
DBMS_OUTPUT.PUT ( ' Dig: ' || l_digit );
DBMS_OUTPUT.PUT ( ' NowSeq: ' || l_seq_val );
DBMS_OUTPUT.PUT ( ' Ret: ' || l_ret_val );
END LOOP;
DBMS_OUTPUT.PUT_LINE ( ' RETURN: ' || l_ret_val );
RETURN l_ret_val;
END;
/
show err
现在测试一下:
select rn, get_seq_val() sv from ( select rownum rn from dual connect by level < 20 );
我的输出:
RN SV
---------- ----------
1 801410
2 610011
3 140441
4 514411
5 341400
6 341100
7 801404
8 301404
9 310014
10 800100
11 615005
12 510500
13 850155
14 205000
15 201000
16 705100
17 550050
18 411555
19 615000
19 rows selected.