Tài liệu đưa ra lý do tại sao bạn có thể thấy sự khác biệt (tôi nhấn mạnh):
Thận trọng:
Vì SQL là ngôn ngữ khai báo chứ không phải là ngôn ngữ mệnh lệnh (hoặc thủ tục), bạn không thể biết hàm được gọi bởi câu lệnh SQL sẽ chạy bao nhiêu lần - ngay cả khi hàm được viết bằng PL / SQL, một ngôn ngữ mệnh lệnh. Nếu ứng dụng của bạn yêu cầu một hàm được thực thi một số lần nhất định, đừng gọi hàm đó từ một câu lệnh SQL. Sử dụng con trỏ để thay thế.
Ví dụ:nếu ứng dụng của bạn yêu cầu một hàm được gọi cho mỗi hàng đã chọn, thì hãy mở một con trỏ, chọn các hàng từ con trỏ và gọi hàm cho mỗi hàng. Kỹ thuật này đảm bảo rằng số lần gọi hàm là số hàng được lấy từ con trỏ.
Về cơ bản, Oracle không chỉ định số lần một hàm sẽ được gọi bên trong câu lệnh sql:nó có thể phụ thuộc vào bản phát hành, môi trường, đường dẫn truy cập cùng các yếu tố khác.
Tuy nhiên, có những cách để hạn chế việc ghi lại truy vấn như được giải thích trong chương Bỏ ghi nhớ các truy vấn con lồng nhau:
Truy vấn con bỏ liên kết không cần thiết và hợp nhất phần nội dung của truy vấn con vào phần nội dung của câu lệnh chứa nó, cho phép trình tối ưu hóa xem xét chúng cùng nhau khi đánh giá các đường dẫn truy cập và các phép nối. Trình tối ưu hóa có thể hủy bỏ hầu hết các truy vấn phụ, với một số ngoại lệ . Những ngoại lệ đó bao gồm các truy vấn con phân cấp và truy vấn con có chứa một cột giả ROWNUM, một trong các toán tử bộ, một hàm tổng hợp lồng nhau hoặc một tham chiếu tương quan đến một khối truy vấn không phải là khối truy vấn bên ngoài ngay lập tức của truy vấn con.
Như đã giải thích ở trên, bạn có thể sử dụng ROWNUM
cột giả để ngăn Oracle bỏ ghi chú một truy vấn con:
SQL> WITH data AS (SELECT SYS_GUID() uuid FROM DUAL WHERE ROWNUM >= 1)
2 SELECT uuid, uuid FROM data;
UUID UUID
-------------------------------- --------------------------------
1ADF387E847F472494A869B033C2661A 1ADF387E847F472494A869B033C2661A