Il y a trois choses qui ne vont pas avec votre SQL dynamique.
- EXECUTE IMMEDIATE n'est pas une fonction :la syntaxe appropriée est
execute immediate '<<query>>' into <<variable>>
. - Une instruction INSERT prend une clause VALUES ou un SELECT mais pas les deux. SELECT serait très faux dans ce cas. Notez également qu'il s'agit de VALEURS et non de VALEUR.
- COLUMN_NAME est un littéral de chaîne dans le SQL dynamique, il doit donc être entre guillemets. Mais comme l'instruction SQL est elle-même une chaîne, les guillemets dans les chaînes dynamiques doivent être échappés. Il doit donc s'agir de `'''||column_name||'''.
La version corrigée ressemblera donc à ceci
declare
Cursor C_TABLE is
select trim(table_name) as table_name
from all_tables
where table_name in ('T1', 'T2', 'T3');
V_ROWNUM number;
begin
for m in C_TABLE
loop
for i in ( select column_name
from (
select c.column_name
from all_tab_columns c
where c.table_name = m.table_name
and c.owner = 'owner1'
)
)
loop
execute immediate 'select count(*) from ' || m.table_name into V_ROWNUM;
execute immediate 'insert into MY_table values ( ''' || i.column_name || ''', ' || V_ROWNUM || ')';
end loop;
end loop;
end;
/
Le SQL dynamique est difficile car il transforme les erreurs de compilation en erreurs d'exécution. Il est recommandé d'écrire d'abord les instructions en SQL statique. Une fois que vous avez la bonne syntaxe de base, vous pouvez la convertir en SQL dynamique.