- Blogzote.com - https://www.blogzote.com -

DBMS_RANDOM en Oracle

Hace algún tiempo recuerdo haber necesitado generar una contraseña aleatoria en Oracle pero al no encontrar una solución fácil nos fuimos por ponerle de contraseña el mismo nombre de usuario, o sea, si era el usuario “fulanito” le pone la contraseña “fulanito”, esto desde un modulo clásico de “olvide mi contraseña”.

Hoy buscando en Internet la solución para otro problema me tope con el paquete dbms_random de oracle, que entre sus funcionalidades esta la generación de una cadena con caracteres aleatorios, hubiera quedado perfecto para el problema que comento, y no solo sirve para eso, sirve también para generar números aleatorios, pudiendo seleccionar el rango en el que estén esos números.

Pero la opción que considero mas importante es que incluso lo puedo utilizar para seleccionar algún registro aleatorio de una tabla. Me recuerda el “ORDER BY RAND()” de Mysql, aunque no es tan “natural” acá en Oracle como lo es en Mysql, les dejo unos ejemplos de su uso, seguro a mas de uno le ayudara a resolver algo.

Una simple consulta para generar un número aleatorio:

SQL> select dbms_random.random from dual;

    RANDOM
----------
-267030442

Pero resulta que nos puede generar números negativos, fácil, usamos el abs:

SQL> select abs(dbms_random.random) from dual;

ABS(DBMS_RANDOM.RANDOM)
-----------------------
              705640851

Bueno pero queremos especificar el rango en el que estén esos números:

SQL> select dbms_random.value(1,10) from dual;

DBMS_RANDOM.VALUE(1,10)
-----------------------
             4.41966315

Pero resulta que me regresa números con decimales, fácil, usamos el round:

SQL> select round(dbms_random.value(1,10)) from dual;

ROUND(DBMS_RANDOM.VALUE(1,10))
------------------------------
                             4

Podemos generar una cadena aleatoria:

SQL> select dbms_random.string('A', 12) from dual;

DBMS_RANDOM.STRING('A',12)
--------------------------------------------------
mQKXSkedaGpK

Aquí la explicación del primer parámetro, el segundo solo es la longitud de la cadena:

'a','A'  alpha characters only (mixed case)
'l','L'  lower case alpha characters only
'p','P'  any printable characters
'u','U'  upper case alpha characters only
'x','X'  any alpha-numeric characters (upper)

Y por ultimo la mejor, podemos obtener un registro aleatorio de una tabla, solo es necesario sustituir “id_campo” por el campo llave de su tabla y por supuesto “mitabla” por el nombre real de su tabla:

select id_campo
  from (select id_campo
          from mitabla
      order by dbms_random.value)
 where rownum = 1

Pero bueno, esa consulta solo me regresa un id, quiero todo el registro, fácil:

select *
  from mitabla mit,
       (select id_campo
          from mitabla
      order by dbms_random.value) idv
 where mit.id_campo = idv.id_campo
   and rownum = 1