sql >> Base de Datos >  >> RDS >> Oracle

Oracle SQL:¿Entiende el comportamiento de SYS_GUID() cuando está presente en una vista en línea?

La documentación da una razón de por qué puede ver una discrepancia (énfasis mío):

Precaución:

Debido a que SQL es un lenguaje declarativo, en lugar de uno imperativo (o de procedimiento), no puede saber cuántas veces se ejecutará una función invocada por una instrucción SQL —incluso si la función está escrita en PL/SQL, un lenguaje imperativo. Si su aplicación requiere que una función se ejecute una cierta cantidad de veces, no invoque esa función desde una instrucción SQL. Utilice un cursor en su lugar.

Por ejemplo, si su aplicación requiere que se llame a una función para cada fila seleccionada, abra un cursor, seleccione filas desde el cursor y llame a la función para cada fila. Esta técnica garantiza que el número de llamadas a la función es el número de filas obtenidas del cursor.

Básicamente, Oracle no especifica cuántas veces se llamará a una función dentro de una instrucción sql:puede depender de la versión, el entorno, la ruta de acceso, entre otros factores.

Sin embargo, hay formas de limitar la reescritura de consultas, como se explica en el capítulo Eliminación de subconsultas anidadas:

El anidamiento de subconsultas anula y fusiona el cuerpo de la subconsulta en el cuerpo de la declaración que lo contiene, lo que permite que el optimizador los considere juntos al evaluar las rutas de acceso y las uniones. El optimizador puede anular la mayoría de las subconsultas, con algunas excepciones . Esas excepciones incluyen subconsultas jerárquicas y subconsultas que contienen una pseudocolumna ROWNUM, uno de los operadores de conjunto, una función agregada anidada o una referencia correlacionada a un bloque de consulta que no es el bloque de consulta externo inmediato de la subconsulta.

Como se explicó anteriormente, puede usar ROWNUM pseudocolumna para evitar que Oracle anule una subconsulta:

SQL> WITH data AS (SELECT SYS_GUID() uuid FROM DUAL WHERE ROWNUM >= 1)
  2  SELECT uuid, uuid FROM data;

UUID                             UUID
-------------------------------- --------------------------------
1ADF387E847F472494A869B033C2661A 1ADF387E847F472494A869B033C2661A