Как выбрать случайное значение из коллекции в PL / SQL?

#sql #oracle #random #plsql

Вопрос:

У меня есть коллекция, полная данных, как выбрать оттуда случайные данные?

 declare
TYPE r_emp_id IS TABLE OF NUMBER;
    emps r_emp_id;
begin
select employes_id into emps from employes order by employes_id;

for i in <(random number of employes_id from emps)> loop

DBMS_OUTPUT.put_line(employes_id (i)); 
end loop;
end;
 

Комментарии:

1. table of number это тип вложенной таблицы, а не ассоциативный массив. table of number index by pls_integer это был бы ассоциативный массив; в вашем коде нет ничего подобного. Пожалуйста, уточните.

Ответ №1:

Вы хотите получить BULK COLLECT INTO коллекцию, а затем вам не нужен цикл, если вам просто нужно одно случайное значение:

 DECLARE
  TYPE r_emp_id IS TABLE OF NUMBER;
  emps r_emp_id;
  i    PLS_INTEGER;
BEGIN
  SELECT employes_id
  BULK COLLECT INTO emps
  FROM   employes
  ORDER BY employes_id;

  i := FLOOR(DBMS_RANDOM.VALUE(1, emps.COUNT   1));

  DBMS_OUTPUT.put_line(emps(i)); 
END;
/
 

Если вы хотите, чтобы все значения были в случайном порядке, то:

 DECLARE
  TYPE r_emp_id IS TABLE OF NUMBER;
  emps r_emp_id;
BEGIN
  SELECT employes_id
  BULK COLLECT INTO emps
  FROM   employes
  ORDER BY DBMS_RANDOM.VALUE;

  FOR i IN 1 .. emps.COUNT LOOP
    DBMS_OUTPUT.put_line(emps(i)); 
  END LOOP;
END;
/
 

Однако для одного значения вы можете полностью пропустить коллекцию:

 DECLARE
  emp_id EMPLOYES.EMPLOYES_ID%TYPE;
BEGIN
  SELECT employes_id
  INTO   emp_id
  FROM   employes
  ORDER BY DBMS_RANDOM.VALUE
  FETCH FIRST ROW ONLY;

  DBMS_OUTPUT.put_line(emp_id); 
END;
/
 

Или в SQL (а не в PL / SQL):

 SELECT employes_id
FROM   employes
ORDER BY DBMS_RANDOM.VALUE
FETCH FIRST ROW ONLY;
 

db<>скрипка здесь