我们能否创建一个给出随机值的PLSQL序列?

can we able to create a PLSQL sequence which gives random values?

提问人:arunkumar-js25 提问时间:12/9/2018 更新时间:12/10/2018 访问量:211

问:

我的问题是关于 PL SQL 序列,它需要在以值开头和最大值之间给出随机值。我们能做到吗?

Oracle PLSQL

评论

0赞 tryingToLearn 12/9/2018
到目前为止,你尝试了什么?
0赞 aldr 12/9/2018
PLSQL生成随机整数的可能副本

答:

2赞 user5683823 12/9/2018 #1

当然,使用 .下面是一个简短的概念证明: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

评论

0赞 arunkumar-js25 12/15/2018
而不是使用 Number..试试Pls_integer。您将获得数字值。
0赞 TenG 12/10/2018 #2

下面是可能有用的替代方法。它不是完全随机的,因为它基本上所做的只是取一个连续的序列号并弄乱数字。为了避免像“100”和“1000”都返回数字“1”,我在起始值中添加了一个随机数字 1-9。

在直随机数上这样做的原因是为了避免返回值中的重复/冲突,这将发生在随机函数中。

当然,您可以使用DBMS_RANDOM方法,并针对目标 table.column 值进行检查,以检查该值尚未使用。

所以,这是我快速而肮脏的随机解决方案:

我还没有彻底测试过。

首先创建一个正常序列:

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.