vendredi 23 août 2019

ORA-29471

Si vous créez du PL/SQL et vous voulez lancer du SQL dynamique dans ce PL/SQL, vous pouvez vous servir de execute immediate. Vous pouvez aussi employer execute immediate si vous avez besoin de lancer DDL (data definition language) dans votre PL/SQL. Ça existe depuis Oracle 8.

Dans Oracle version 7 il fallait se servir de dbms_sql pour lancer SQL dynamique ou DDL dans PL/SQL.

Récemment, j’ai trouvé un exemple de dbms_sql dans une base de données Oracle 11. Le PL/SQL avait été créé il y a longtemps. La base avait été mise à jour de version 7 à version 8. La base avait été mise à jour de version 8 à version 9. La base avait été mise à jour de version 9 à version 11. Mais personne n’avait changé le PL/SQL.

J’ai découvert ce PL/SQL quand il a commencé à produire des erreurs ORA-29471.

D’abord, voici un exemple simple de dbms_sql, qui crée une table :


SQL> declare
  2   sql_statement varchar2(200);
  3   sql_cursor integer;
  4  begin
  5   sql_statement := 'create table tab1(col1 number)';
  6   sql_cursor := dbms_sql.open_cursor;
  7   dbms_sql.parse(sql_cursor, sql_statement, dbms_sql.native);
  8   dbms_sql.close_cursor(sql_cursor);
  9  end;
 10  /

PL/SQL procedure successfully completed.

SQL> desc tab1
Name                       Null?    Type
-------------------------- -------- ------------------
COL1                                NUMBER

SQL>

Si on se trompe et on essaie (par exemple) de fermer un cursor qu’on n’a pas ouvert, Oracle vous rend une erreur ORA-29471 :


SQL> declare
  2   sql_cursor integer;
  3  begin
  4   dbms_sql.close_cursor(sql_cursor);
  5  end;
  6  /
declare
*
ERROR at line 1:
ORA-29471: DBMS_SQL access denied
ORA-06512: at "SYS.DBMS_SQL", line 1046
ORA-06512: at line 4

SQL>