EXECUTE IMMEDIATE

 

In un blocco PL/SQL non è possibile includere direttamente le istruzioni di DDL (Data Definition Language), ma solo quelle di DML (Data Manipulation Language). Se tentassimo l’esecuzione del codice:

BEGIN
    CREATE TABLE TEST(ID NUMBER);
END;

otterremmo un’eccezione del tipo:

PLS-00103: Encountered the symbol "CREATE" when expecting one of the following:
           ( begin case declare exit for goto if loop mod null pragma...

Un escamotage per aggirare la limitazione è l’utilizzo dell’istruzione EXECUTE IMMEDIATE che consente di eseguire un’istruzione SQL contenuta nella stringa passatagli come parametro. E’ una specie di esecuzione indiretta, precedura da una prima fase di parsing sintattico del parametro.

BEGIN
    EXECUTE IMMEDIATE 'CREATE TABLE TEST(ID NUMBER)';
END;

Che io sappia, non esistono limitazioni sulla tipologia di SQL da passare all’istruzione. Maggiori dettagli si possono trovare qui.

 

ESEMPI

  1. La stringa di comando è composta tramite concatenazione di stringhe. L’output della query viene memorizzato nelle variabili per mezzo della keyword INTO.

    DECLARE
      v_field NUMBER := 6;
    v_sql VARCHAR2(4000) := 'SELECT COUNT(*) FROM TEST WHERE ID = ' || v_field;
    v_count NUMBER;
    BEGIN
    EXECUTE IMMEDIATE v_sql INTO v_count;
    DBMS_OUTPUT.put_line('Results = ' || v_count);
    END;

  2. La stringa di comando è composta da una query predefinita dove il bind fra i parametri formali e quelli della chiamata viene realizzato dalla keyword USING. La sostituzione dei parametri della query, preceduti da un colon (:), avviene posizionalmente.

    DECLARE
      v_field NUMBER := 6;
    v_sql VARCHAR2(4000) := 'SELECT COUNT(*) FROM TEST WHERE ID = :field';
    v_count NUMBER;
    BEGIN
    EXECUTE IMMEDIATE v_sql USING v_field INTO v_count;
    DBMS_OUTPUT.put_line('Results = ' || v_count);
    END;

  3. Ecco un esempio di invocazione della funzione di un package, con tanto di passaggio di parametri.
    La funzione/procedura deve essere necessariamente preceduta dalla keyword CALL.
    I parametri della funzione sono elencati dopo la USING e prima di ognuno di essi bisogna specificarne la direzione (IN – default, IN OUT, OUT).
    Il return code della funzione deve essere esplicitato nella stringa di comando con una INTO e deve essere indicato come ultimo parametro di OUT nella USING.

    DECLARE
      v_id NUMBER := 5;
    v_type VARCHAR2(20) := 'Object';
    v_sql VARCHAR2(4000) := 'PKG_OBJECTS.Get_Name(:id, :tipo, :name)';
    v_name VARCHAR2(255);
    v_found NUMBER(1);
    BEGIN
    EXECUTE IMMEDIATE 'CALL ' || v_sql || ' INTO :found' USING v_id, v_type, OUT v_name, OUT v_found;
    DBMS_OUTPUT.put_line('Found = ' || v_found);
    DBMS_OUTPUT.put_line('Name = ' || v_name);

    END;

 

Lascia un commento