Đánh giá lười biếng có thể được thực hiện (một phần) bằng cách sử dụng con trỏ tham chiếu, biên dịch có điều kiện hoặc thực thi ngay lập tức. Loại ANYDATA có thể được sử dụng để chuyển dữ liệu chung.
Con trỏ tham chiếu
Con trỏ tham chiếu có thể được mở bằng một câu lệnh SQL tĩnh, được truyền dưới dạng đối số và sẽ không thực thi cho đến khi cần thiết.
Mặc dù điều này thực sự trả lời câu hỏi của bạn về đánh giá lười biếng, nhưng tôi không chắc liệu nó có thực sự thực tế hay không. Đây không phải là mục đích sử dụng con trỏ tham chiếu. Và có thể không thuận tiện khi phải thêm SQL vào mọi thứ.
Đầu tiên, để chứng minh rằng hàm chậm đang chạy, hãy tạo một hàm chỉ ngủ trong vài giây:
grant execute on sys.dbms_lock to <your_user>;
create or replace function sleep(seconds number) return number is
begin
dbms_lock.sleep(seconds);
return 1;
end;
/
Tạo một hàm để xác định xem việc đánh giá có cần thiết hay không:
create or replace function do_i_have_to_trace return boolean is
begin
return true;
end;
/
Hàm này có thể thực hiện công việc bằng cách thực thi câu lệnh SQL. Câu lệnh SQL phải trả về một cái gì đó, mặc dù bạn có thể không muốn một giá trị trả về.
create or replace procedure trace_something(p_cursor sys_refcursor) is
v_dummy varchar2(1);
begin
if do_i_have_to_trace then
fetch p_cursor into v_dummy;
end if;
end;
/
Bây giờ, hãy tạo thủ tục sẽ luôn gọi theo dõi nhưng sẽ không nhất thiết phải dành thời gian đánh giá các đối số.
create or replace procedure lazily_trace_something(some_number in number) is
v_cursor sys_refcursor;
begin
open v_cursor for select sleep(some_number) from dual;
trace_something(v_cursor);
end;
/
Theo mặc định, nó đang hoạt động và chậm:
--Takes 2 seconds to run:
begin
lazily_trace_something(2);
end;
/
Nhưng khi bạn thay đổi DO_I_HAVE_TO_TRACE
để trả về false thì thủ tục này rất nhanh, ngay cả khi nó truyền một đối số chậm.
create or replace function do_i_have_to_trace return boolean is
begin
return false;
end;
/
--Runs in 0 seconds.
begin
lazily_trace_something(2);
end;
/
Các tùy chọn khác
Biên dịch có điều kiện được sử dụng truyền thống hơn để bật hoặc tắt thiết bị đo đạc. Ví dụ:
create or replace package constants is
c_is_trace_enabled constant boolean := false;
end;
/
declare
v_dummy number;
begin
$if constants.c_is_trace_enabled $then
v_dummy := sleep(1);
This line of code does not even need to be valid!
(Until you change the constant anyway)
$else
null;
$end
end;
/
Bạn cũng có thể muốn xem xét lại SQL động. Phong cách lập trình và một số cú pháp có thể tạo ra sự khác biệt lớn ở đây. Tóm lại, cú pháp trích dẫn thay thế và các mẫu đơn giản có thể làm cho SQL động dễ đọc hơn nhiều. Để biết thêm chi tiết, hãy xem bài đăng của tôi tại đây .
Truyền dữ liệu chung
Có thể sử dụng BẤT KỲ loại nào để lưu trữ và chuyển bất kỳ kiểu dữ liệu nào có thể tưởng tượng được. Rất tiếc, không có kiểu dữ liệu gốc nào cho mỗi loại hàng. Bạn sẽ cần tạo một LOẠI cho mỗi bảng. Các loại tùy chỉnh đó rất đơn giản nên bước này có thể được tự động hóa nếu cần.
create table some_table(a number, b number);
create or replace type some_table_type is object(a number, b number);
declare
a_rowtype_variable some_table_type;
v_anydata anydata;
v_cursor sys_refcursor;
begin
a_rowtype_variable := some_table_type(1,2);
v_anydata := anydata.ConvertObject(a_rowtype_variable);
open v_cursor for select v_anydata from dual;
trace_something(v_cursor);
end;
/