Lazy Evaluation kann (teilweise) mit Ref-Cursorn, bedingter Kompilierung oder sofortiger Ausführung implementiert werden. Der ANYDATA-Typ kann verwendet werden, um generische Daten zu übergeben.
Referenz-Cursor
Ref-Cursor können mit einer statischen SQL-Anweisung geöffnet, als Argumente übergeben und erst ausgeführt werden, wenn sie benötigt werden.
Während dies Ihre Frage zur faulen Bewertung buchstäblich beantwortet, bin ich mir nicht sicher, ob es wirklich praktisch ist. Dies ist nicht die beabsichtigte Verwendung von Ref-Cursorn. Und es ist möglicherweise nicht bequem, SQL zu allem hinzufügen zu müssen.
Um zu beweisen, dass die langsame Funktion ausgeführt wird, erstellen Sie zunächst eine Funktion, die einfach für ein paar Sekunden schläft:
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;
/
Erstellen Sie eine Funktion, um festzustellen, ob eine Auswertung erforderlich ist:
create or replace function do_i_have_to_trace return boolean is
begin
return true;
end;
/
Diese Funktion kann die Arbeit ausführen, indem sie die SQL-Anweisung ausführt. Die SQL-Anweisung muss etwas zurückgeben, auch wenn Sie keinen Rückgabewert wünschen.
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;
/
Erstellen Sie nun die Prozedur, die immer Trace aufruft, aber nicht unbedingt Zeit mit der Auswertung der Argumente verbringt.
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;
/
Standardmäßig erledigt es die Arbeit und ist langsam:
--Takes 2 seconds to run:
begin
lazily_trace_something(2);
end;
/
Aber wenn Sie DO_I_HAVE_TO_TRACE
ändern Um false zurückzugeben, ist die Prozedur schnell, obwohl sie ein langsames Argument übergibt.
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;
/
Andere Optionen
Die bedingte Kompilierung wird traditioneller verwendet, um die Instrumentierung zu aktivieren oder zu deaktivieren. Zum Beispiel:
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;
/
Vielleicht möchten Sie auch dynamisches SQL überdenken. Programmierstil und etwas syntaktischer Zucker können hier einen großen Unterschied machen. Kurz gesagt, die alternative Zitatsyntax und einfache Vorlagen können dynamisches SQL viel besser lesbar machen. Weitere Einzelheiten finden Sie in meinem Post hier .
Generische Daten weitergeben
Die ANY-Typen können verwendet werden, um jeden erdenklichen Datentyp zu speichern und zu übergeben. Leider gibt es keinen nativen Datentyp für jeden Zeilentyp. Sie müssen für jede Tabelle einen TYPE erstellen. Diese benutzerdefinierten Typen sind sehr einfach, sodass dieser Schritt bei Bedarf automatisiert werden kann.
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;
/