注意,尽管在内联视图/ with子句中构建了UUID值,但是结果集中的UUID值是不同的(一个有898对象有899个)。下面你可以看到DBMS_RANDOM.RANDOM()没有这个副作用。
sql:
WITH data AS (SELECT SYS_GUID () uuid FROM DUAL) SELECT uuid,uuid FROM data
输出:
UUID UUID_1 F8FCA4B4D8982B55E0440000BEA88F11 F8FCA4B4D8992B55E0440000BEA88F11
在对比度DBMS_RANDOM中,结果是一样的
sql:
WITH data AS (SELECT DBMS_RANDOM.RANDOM() rand FROM DUAL) SELECT rand,rand FROM data
输出:
RAND RAND_1 92518726 92518726
更有趣的是,我可以通过将调用包括到DBMS_RANDOM.RANDOM来改变行为/稳定sys_guid:
WITH data AS ( SELECT SYS_GUID () uuid,DBMS_RANDOM.random () rand FROM DUAL) SELECT uuid a,uuid b,rand c,rand d FROM data
稳定的sql小提琴SYS_GUID:
http://sqlfiddle.com/#!4/d41d8/29409
sql Fiddle显示奇怪的SYS_GUID行为:
http://sqlfiddle.com/#!4/d41d8/29411
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.
基本上,Oracle没有指定在sql语句中调用一个函数的次数:它可能取决于发行版本,环境,访问路径等因素。
但是,有一些方法来限制查询重写,如第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.
如上所述,您可以使用ROWNUM
伪列来防止Oracle不察觉子查询:
sql> WITH data AS (SELECT SYS_GUID() uuid FROM DUAL WHERE ROWNUM >= 1) 2 SELECT uuid,uuid FROM data; UUID UUID -------------------------------- -------------------------------- 1ADF387E847F472494A869B033C2661A 1ADF387E847F472494A869B033C2661A