Генерация случайных букв верхнего и нижнего регистра в Oracle - PullRequest
12 голосов
/ 05 апреля 2011

Как можно генерировать прописную и строчную буквенно-цифровую случайную строку из оракула?

Я использовал select DBMS_RANDOM.STRING('x', 10) from dual для генерации буквенно-цифровых символов в верхнем регистре

и select DBMS_RANDOM.STRING('a', 10) from dual для генерации букв верхнего и нижнего регистра

... но мне бы хотелось, чтобы функция выполняла как прописные, так и прописные буквы, а также буквенные и цифровые символы.

Кроме того, бонусные баллы (или просто положительные отзывы), если вы можете вспомнить веские причины, почему Oracle не реализовал это?

Ответы [ 6 ]

10 голосов
/ 05 апреля 2011

Вы можете сделать свою собственную функцию. Это один из вариантов:

create or replace function random_str(v_length number) return varchar2 is
    my_str varchar2(4000);
begin
    for i in 1..v_length loop
        my_str := my_str || dbms_random.string(
            case when dbms_random.value(0, 1) < 0.5 then 'l' else 'x' end, 1);
    end loop;
    return my_str;
end;
/

select random_str(30) from dual;

RANDOM_STR(30)
--------------------------------------------------------------------------------
pAAHjlh49oZ2xuRqVatd0m1Pv8XuGs

Возможно, вы захотите настроить 0.5 для учета различных размеров пула - 26 для l против 36 для x. (.419354839?). Вы также можете использовать value () и передать начальный и конечный диапазон значений символов, но это будет зависеть от набора символов.

А почему ... Oracle нужна причина? Использование x может указывать на то, что изначально оно было шестнадцатеричным и было расширено, чтобы включить все заглавные буквы, при этом им не приходило добавлять одновременно смешанную версию.

9 голосов
/ 05 апреля 2011

Попробуйте,

with
  r as (
    select
      level lvl,
      substr(
        'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789',
        mod(abs(dbms_random.random), 62)+1, 1) a
    from dual connect by level <= 10
  )
select
  replace(sys_connect_by_path(a, '/'), '/') random_string
from r
where lvl = 1
start with lvl = 10
connect by lvl + 1 = prior lvl
;

Вывод,

FOps2k0Pcy
3 голосов
/ 20 января 2013
CREATE OR REPLACE FUNCTION fn_mac RETURN varchar2 IS
   w number :=0;
   a varchar2(10);
   b varchar2(50);
   x number :=0;
   y number :=0;
   z number :=0;
   c varchar2(50);
   result varchar2(20);
  BEGIN
  select round(dbms_random.value(1,99))into w from dual;
  SELECT upper(dbms_random.string('A', 2))into a FROM dual;
  SELECT round(dbms_random.value(1, 9)) into x FROM dual;
  SELECT upper(dbms_random.string('A', 4)) into b FROM dual;
  SELECT round(dbms_random.value(1, 9)) into y FROM dual;
  SELECT upper(dbms_random.string('A', 1)) into c FROM dual;
  SELECT round(dbms_random.value(1, 9)) into z FROM dual;
   result :=(  to_char(w) ||a|| to_char(x)|| b|| to_char(y)|| c ||to_char(z)) ;
   DBMS_OUTPUT.PUT_LINE( 'Result ::' || result);
   RETURN result ;
  END fn_mac;
  /
1 голос
/ 06 апреля 2011

Вы можете начать с параметра печати, а затем удалить любые не алфавитно-цифровые символы:

select SUBSTR(
         TRANSLATE(dbms_random.string('p',100)
            ,'A`~!@#$%^&*()-=_+[]\{}|;'':",./<>?'
            ,'A')
       ,1,10) from dual;

(Примечание: очень редко это будет возвращать менее 10 символов)

или,сопоставьте оскорбительные символы с другими буквами и цифрами (хотя это немного уменьшило бы случайность):

select TRANSLATE(dbms_random.string('p',10)
            ,'A`~!@#$%^&*()-=_+[]\{}|;'':",./<>? '
            ,'A' || dbms_random.string('x',33)) from dual;

Кстати, отличный вопрос.

Теперь, для моих бонусных очков:

Причина, по которой Oracle не реализовал это, заключается в том, что никто не просил об этом, и это, вероятно, не является высоким приоритетом.

1 голос
/ 05 апреля 2011

Как насчет этого:

select translate(dbms_random.string('a', 20), 'abcXYZ', '158249') from dual;

или, даже более случайный;)

select translate(dbms_random.string('a', 20), dbms_random.string('a',6), trunc(dbms_random.value(100000,999999))) from dual;
0 голосов
/ 10 ноября 2013
create or replace procedure r1
    is
    v_1 varchar2(1);
    v_2 varchar2(10);
    begin 
    for inner_c in 1..10
    loop
    select  substr('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789',mod(abs(dbms_random.random), 62)+1, 1) into v_1 from dual;
    v_2 := v_2 || v_1;
    end loop;
    dbms_output.put_line(v_2);
    end;
    /
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...