Можем ли мы создать последовательность PLSQL, которая дает случайные значения? - PullRequest
0 голосов
/ 09 декабря 2018

Мой вопрос касается последовательности SQL PL, которая должна давать случайные значения от начала до значения.Можем ли мы сделать это?

Ответы [ 2 ]

0 голосов
/ 09 декабря 2018

Вот альтернативный подход, который может быть полезен.Это не совсем случайно, так как все, что он в основном делает, это берет последовательный порядковый номер и перемешивает цифры.Чтобы избежать появления таких вещей, как «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

Теперь TEst it:

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.
0 голосов
/ 09 декабря 2018

Конечно, используйте 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...