问题
In an Oracle PL/SQL block, why is dynamic sql allowed
begin
execute immediate 'drop table table_name';
end;
but static is not?
begin
drop table table_name;
end;
I hope the answer is more insightful than "because that's how the language works".
回答1:
The answer is PL/SQL does not support dynamic polymorphism. it only supports static polymorphism because
All PL/SQL generats a "DIANA" -> Descriptive Intermediate Attributed Notation for Ada , a tree-structured intermediate language. DIANA is used internally by compilers.
At compile time, PL/SQL source code is translated into system code and generates corresponding DIANA. Now think if there were a DDL statement like create table statement which at the compile time does not exists it will be created after running the program. how would your PL/SQL engine generate a DIANA then ????
The DIANA is plays an important role in PL/SQL to check/validate that the sub program. this is required because as we know that a sub-program can use database objects such as Tables,Views,Synonyms or other stored procs. it could be possible that the the objects may have changed/removed/droped when next time you run the program. For ex : some one might have droped the table, the stored proc or function singnature may have changed.
Thats why generally PL/SQL is used to manipulate the data within database structure, but not to manipulate those structures.
but there are ways to manipulate using dynamic SQL and DBMS_SQL package but theses methodlogy are again should be used cautiously. For example if you are creating a Table you should check first if this table is already exists or not using data dictionary views.
回答2:
Probably because otherwise some code would be like:
begin
create table tmp (n number);
insert into tmp values (1);
end;
And we would expect the compiler to know that at time of the insert, the table exists. The compilation of the block would me much more difficult. Here it is a very simple case, but we can easily imagine some conditional branching, and complex blabla.
But, since we need to put the DDL in an execute immediate block, the limitation maybe somehow easier to understand.
Just an idea...
回答3:
Before execution/compilation, oracle checks all access permissions,validity and dependencies of all schema objects like tables,views,stored procs etc referenced inside a pl/sql block. But problem with DDL statement is that it can create, alter or drop schema object and as a result, it can change the object dependencies.So it is possible that we are referring one object which has been dropped using DDL. To prevent such situation I guess plsql block does not allow direct DDL statement. But we can still include DDL in PL/SQL block using Dynamic query. As in this case the actual query is not known until run-time, basically we can hide the DDL statement in the form of Dynamic SQL and include DDL inside PL/SQL block.
You can refer my blog to understand the concept with example: Why oracle does not allow direct DDL statements inside the procedure (PLSQL BLOCK)
来源:https://stackoverflow.com/questions/15232252/why-is-static-ddl-not-allowed-in-pl-sql