Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Składnia do niestandardowej leniwej oceny / krótkiego obwodu parametrów funkcji

Ocena z opóźnieniem może być (częściowo) zaimplementowana za pomocą kursorów ref, kompilacji warunkowej lub natychmiastowego wykonania. Typ ANYDATA może być używany do przekazywania ogólnych danych.

Kursor referencji

Kursory referencji mogą być otwierane za pomocą statycznej instrukcji SQL, przekazywanej jako argumenty i nie będą wykonywane, dopóki nie będą potrzebne.

Chociaż to dosłownie odpowiada na twoje pytanie dotyczące leniwej oceny, nie jestem pewien, czy jest to naprawdę praktyczne. To nie jest zamierzone użycie kursorów ref. I może nie być wygodne dodawanie SQL do wszystkiego.

Po pierwsze, aby udowodnić, że powolna funkcja działa, utwórz funkcję, która po prostu śpi przez kilka sekund:

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

Utwórz funkcję, aby określić, czy ocena jest konieczna:

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

Ta funkcja może wykonać pracę, wykonując instrukcję SQL. Instrukcja SQL musi coś zwrócić, nawet jeśli nie chcesz zwracać wartości.

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

Teraz utwórz procedurę, która zawsze będzie wywoływać trace, ale niekoniecznie będzie spędzać czas na ocenie argumentów.

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

Domyślnie wykonuje swoją pracę i jest powolny:

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

Ale kiedy zmienisz DO_I_HAVE_TO_TRACE aby zwrócić false procedura jest szybka, nawet jeśli przekazuje powolny 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;
/

Inne opcje

Kompilacja warunkowa jest tradycyjnie używana do włączania lub wyłączania instrumentacji. Na przykład:

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żesz również rozważyć ponowne rozważenie dynamicznego SQL. Styl programowania i trochę cukru składniowego mogą tutaj zrobić dużą różnicę. Krótko mówiąc, alternatywna składnia cytatów i proste szablony mogą znacznie zwiększyć czytelność dynamicznego SQL. Aby uzyskać więcej informacji, zobacz mój post tutaj .

Przekazywanie danych ogólnych

Typy ANY mogą służyć do przechowywania i przekazywania dowolnego możliwego do wyobrażenia typu danych. Niestety nie ma natywnego typu danych dla każdego typu wiersza. Musisz utworzyć TYP dla każdej tabeli. Te niestandardowe typy są bardzo proste, więc w razie potrzeby krok można zautomatyzować.

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Znak ucieczki Oracle SQL (dla „&”)

  2. Superkey, klucz kandydujący i klucz podstawowy

  3. Nie można zarejestrować się w transakcji rozproszonej z NHibernate

  4. Błąd:ORA-00955:nazwa jest już używana przez istniejący obiekt w funkcji Oracle

  5. Spróbuj przekonwertować czas na sekundy w Oracle SQL