sql >> Databáze >  >> RDS >> Oracle

Syntaxe pro vlastní líné vyhodnocení/zkratování parametrů funkcí

Líné vyhodnocení může být (částečně) implementováno pomocí referenčních kurzorů, podmíněné kompilace nebo okamžitého provedení. Typ ANYDATA lze použít k předávání obecných dat.

Referenční kurzor

Referenční kurzory lze otevřít pomocí statického příkazu SQL, předat je jako argumenty a nespustí se, dokud to nebude nutné.

I když to doslova odpovídá na vaši otázku o líném hodnocení, nejsem si jistý, zda je to skutečně praktické. Toto není zamýšlené použití referenčních kurzorů. A nemusí být vhodné ke všemu přidávat SQL.

Nejprve, abyste prokázali, že pomalá funkce běží, vytvořte funkci, která jednoduše na několik sekund usne:

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;
/

Vytvořte funkci, která určí, zda je vyhodnocení nezbytné:

create or replace function do_i_have_to_trace return boolean is
begin
    return true;
end;
/

Tato funkce může provádět práci provedením příkazu SQL. Příkaz SQL musí něco vrátit, i když návratovou hodnotu možná nechcete.

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;
/

Nyní vytvořte proceduru, která bude vždy volat trace, ale nebude nutně trávit čas vyhodnocováním argumentů.

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;
/

Ve výchozím nastavení dělá práci a je pomalý:

--Takes 2 seconds to run:
begin
    lazily_trace_something(2);
end;
/

Ale když změníte DO_I_HAVE_TO_TRACE pro návrat false je procedura rychlá, i když předává pomalý argument.

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;
/

Další možnosti

Podmíněná kompilace se tradičně používá k povolení nebo zakázání instrumentace. Například:

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;
/

Možná budete chtít znovu zvážit dynamické SQL. Styl programování a nějaký syntaktický cukr zde mohou udělat velký rozdíl. Stručně řečeno, alternativní syntaxe citací a jednoduché šablony mohou učinit dynamický SQL mnohem čitelnějším. Další podrobnosti najdete v mém příspěvku zde .

Předávání obecných dat

ANY typy lze použít k uložení a předání jakéhokoli představitelného datového typu. Bohužel neexistuje žádný nativní datový typ pro každý typ řádku. Pro každou tabulku budete muset vytvořit TYPE. Tyto vlastní typy jsou velmi jednoduché, takže krok lze v případě potřeby automatizovat.

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;
/



  1. group_concat a jak používat číslo řádku ve sqlite

  2. Jak vytvořit a nasadit Azure Database for MySQL Server pomocí Azure Portal a Workbench

  3. Export konkrétních sloupců z tabulky Mysql do Excelu

  4. Porovnání proměnných nvarchar v t-sql