it-swarm-eu.dev

Proč nemůžeme psát příkaz ddl přímo do bloku PL / SQL

Proč nemůžeme psát příkazy ddl přímo v PL/SQL bloku, například když píšu

CREATE OR REPLACE PROCEDURE test IS
BEGIN
    truncate table table_name; // error
END test;
/

Ale,

CREATE OR REPLACE PROCEDURE test IS
BEGIN
    execute immediate 'truncate table table_name'; // works fine
END test;
/

Proč druhý úspěšně proveden?

11
Ravi

Jak je uvedeno v dokumentace :

Pouze dynamický SQL může provádět následující typy příkazů v programových jednotkách PL/SQL:

  • Příkazy jazyka DDL (Data Definition Language) jako CREATE, DROP, GRANT a REVOKE

Operace TRUNCATE je DDL.

Při použití EXECUTE IMMEDIATE, pamatujte, že všechny operace DDL, které provedete, implicitně COMMIT aktuální transakci.

7
Philᵀᴹ

DDL uvnitř PL/SQL kódu je více výjimka, než je skutečná potřeba. Parse lze považovat za ověření struktury, které se ztratí, pokud se struktura při provádění změní. Účelem procedur je opět analyzovat další objekty (tabulky nebo jiný kód pl/sql, pohledy atd.). Při každé změně objektu by měl být překompilován. Takže, analyzovaný kód něčeho než struktura změny nemůže být ověřen a jako takový kompilován. Zvažte případ

DROP TABLE T1;

Během analýzy se najde tabulka a procedura se úspěšně zkompiluje, ale při prvním spuštění je tabulka zrušena a váš kód již není platný (příště DROP TABLE by vyústila v chybu). Podobně jakákoli změna v tabulce DDL by vytvořila potřebu překompilovat, a tak ztratit výhodu analýzy kódu.

1
igr