-------------------------------------------------------------------------------
-- corr_pl_sqldyn2.sql 
-- 9 octobre 2013
-------------------------------------------------------------------------------
-- 8.1 
-- ordre DDL (methode 1), select, boucle avec variables

create or replace procedure duplique_gen (
  t varchar2, a varchar2, b varchar2, c varchar2, d varchar2) 
  authid current_user -- voir remarque ci-dessous
is
  texte varchar2(100); 
  texte2 varchar2(100); 
  cur sys_refcursor;
  x1 int;
  x2 varchar2(10);
  x3 int;
  x4 int;
begin
  -- on vise la chaine suivante ou u, v, w, x, y sont les parametres actuels :
  -- 'create table u2(v2 int, w2 varchar2(10), x2 int, y2 int)'
  texte := 'create table '||t||'2('||a||'2 int, '||b|| '2 varchar2(10), '
                          ||c||'2 int, '||d||'2 int)';
  dbms_output.put_line(texte);
  execute immediate texte;
  
  -- on vise la chaine suivante ou u est le parametre actuel nom de la table :
  -- insert into u2 values(:1, :2, :3, :4)
  texte := 'insert into '||t||'2 values(:1, :2, :3, :4)';
  dbms_output.put_line(texte);
  texte2 := 'select * from '||t;
  dbms_output.put_line(texte2);
  open cur for texte2;
  loop
    fetch cur into x1, x2, x3, x4; 
    exit when cur%notfound;
    execute immediate texte using x1, x2, x3, x4;
  end loop;
end;
/
show errors

/* rem : authid current_user permet d'executer une procedure avec les droits de
  celui qui execute le code (definer rights) par opposition au mode par defaut
  ou le code PL/SQL s'execute avec les droits celui qui a compile le code 
  (invoker rights) ; ici la table est creee chez celui qui execute la procedure
  c'est donc lui qui doit avoir les droits. 
*/

set serveroutput on
select * from client;
drop table client2;
exec duplique_gen('client', 'idc', 'nom', 'age', 'avoir');
select * from client;
select * from client2;
-- tester aussi avec table client vide

-------------------------------------------------------------------------------
-- 8.4
-- select

create or replace procedure affiche_gen (t varchar2, a varchar2, b varchar2) is
  texte varchar2(100); 
  cur sys_refcursor;
  x1 varchar2(10);
  x2 int;
begin
  texte := 'select '||a||','||b||' from '||t;
  dbms_output.put_line(texte);
  open cur for texte;
  loop
    fetch cur into x1, x2; 
    exit when cur%notfound;
      dbms_output.put_line(x1||', '||x2);
  end loop;
end;
/
show errors

set serveroutput on
select * from client;
exec affiche_gen('client', 'nom', 'age');
select * from client;

-------------------------------------------------------------------------------
-- remerciements :
-- certains de ces codes ont utilise des codes de Sophie Laplante 2006 et 2007
-- et de Jesus Camacho-Rodriguez 2012 et 2013
-------------------------------------------------------------------------------
