Oracle SQL: Understanding the behavior of SYS_GUID() when present in an inline view?

后端 未结 3 1226
失恋的感觉
失恋的感觉 2020-12-29 05:57

Here is the example SQL in question; The SQL should run on any Oracle DBMS (I\'m running 11.2.0.2.0).

Note how the UUID values are different (one has 898 the other

3条回答
  •  春和景丽
    2020-12-29 06:51

    The documentation gives a reason as to why you may see a discrepancy (emphasis mine):

    Caution:

    Because SQL is a declarative language, rather than an imperative (or procedural) one, you cannot know how many times a function invoked by a SQL statement will run—even if the function is written in PL/SQL, an imperative language. If your application requires that a function be executed a certain number of times, do not invoke that function from a SQL statement. Use a cursor instead.

    For example, if your application requires that a function be called for each selected row, then open a cursor, select rows from the cursor, and call the function for each row. This technique guarantees that the number of calls to the function is the number of rows fetched from the cursor.

    Basically, Oracle doesn't specify how many times a function will be called inside a sql statement: it may be dependent upon the release, the environment, the access path among other factors.

    However, there are ways to limit query rewrite as explained in the chapter Unnesting of Nested Subqueries:

    Subquery unnesting unnests and merges the body of the subquery into the body of the statement that contains it, allowing the optimizer to consider them together when evaluating access paths and joins. The optimizer can unnest most subqueries, with some exceptions. Those exceptions include hierarchical subqueries and subqueries that contain a ROWNUM pseudocolumn, one of the set operators, a nested aggregate function, or a correlated reference to a query block that is not the immediate outer query block of the subquery.

    As explained above, you can use ROWNUM pseudo-column to prevent Oracle from unnesting a subquery:

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

提交回复
热议问题