2010-01-07 43 views
7

Có ai biết, tại sao hàm NVL (và NVL2) của Oracle luôn đánh giá tham số thứ hai, ngay cả khi tham số đầu tiên không phải là NULL?Tại sao NVL luôn đánh giá tham số thứ 2

đơn giản kiểm tra:

CREATE FUNCTION nvl_test RETURN NUMBER AS 
BEGIN 
    dbms_output.put_line('Called'); 
    RETURN 1; 
END nvl_test; 

SELECT NVL(0, nvl_test) FROM dual

lợi nhuận 0, mà còn in Called.

nvl_test đã được gọi, mặc dù kết quả bị bỏ qua vì tham số đầu tiên không phải là NULL.

Trả lời

8

Nó luôn luôn như vậy, vì vậy Oracle phải giữ nó theo cách đó để duy trì tương thích ngược.

Sử dụng COALESCE để thay thế hành vi đoản mạch.

+1

Lưu ý: không ngắn mạch trong 9i. –

3

Nói chung, nó sẽ làm cho cảm giác rằng tham số thứ hai được đánh giá trước khi gọi hàm, bởi vì nói chung đó là cách các chức năng này được gọi là: tất cả các tham số cho hàm được đánh giá và các giá trị được đánh giá được gửi đến hàm.

Tuy nhiên, trong trường hợp có chức năng hệ thống rất phổ biến như NVL, tôi đã nghĩ PL/SQL có thể tối ưu hóa, xử lý cuộc gọi hàm như một trường hợp đặc biệt. Nhưng có lẽ đó là khó khăn hơn nó âm thanh (với tôi), như tôi chắc chắn tối ưu hóa này sẽ xảy ra với các nhà phát triển của Oracle.

5

Đây là một bài đăng mà Tom Kyte xác nhận rằng decodecase ngắn mạch nhưng không phải là nvl nhưng anh ấy không đưa ra lý giải hoặc tài liệu về lý do. Chỉ cần nói nó là:

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:926029357278#14932880517348

Vì vậy, trong trường hợp của bạn, bạn nên sử dụng decode hoặc case thay vì nvl nếu một chức năng đắt tiền sẽ được gọi trong truy vấn của bạn.

Các vấn đề liên quan