Précédent   Forum des professionnels en informatique > Bases de données > Oracle > SQL
SQL Forum d'entraide sur le SQL pour Oracle
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 21/04/2008, 17h32   #1
Membre habitué
 
Avatar de ruscov
 
Inscription : mars 2007
Messages : 134
Détails du profil
Informations personnelles :
Âge : 27
Localisation : Belgique

Informations forums :
Inscription : mars 2007
Messages : 134
Points : 145
Points : 145
Par défaut INSERT INTO avec un SELECT et SUBQUERY

Bonjour à tous,

Pour mon projet je dois faire des triggers dans ma DB. Je tombe sur des "mutatings table". Dès lors je tente d'appliquer la méthode des deux déclencheurs avec table temporaire. ( la théorie )

Pour remplir ma table temporaire, plutôt que faire un INSERT INTO avec un VALUES et citer chacune de mes colonnes, j'aimerais insérer directement tout mon record "new" de la ligne. Car j'ai des tables qui ont pas mal de colonnes... Cela me permettrait de gagner pas mal de temps!

En pratique, au lieu de :
Code ORACLE :
1
2
3
4
5
 
CREATE OR REPLACE TRIGGER TRIG_INSCRIPTION BEFORE INSERT ON INSCRIPTION FOR EACH ROW
BEGIN
    INSERT INTO TEMP_INSCRIPTION(IDC, IDV, DATERESERV) VALUES (:NEW.IDC, :NEW.IDV, :NEW.DATERESERV);
END ;

j'aimerais un truc du style :
Code ORACLE :
1
2
3
4
5
 
CREATE OR REPLACE TRIGGER TRIG_INSCRIPTION BEFORE INSERT ON INSCRIPTION FOR EACH ROW
BEGIN
    INSERT INTO TEMP_INSCRIPTION(IDC, IDV, DATERESERV) VALUES( :NEW )
END ;
Est-ce possible?? Merci beaucoup!
ruscov est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/04/2008, 18h11   #2
McM
Expert Confirmé Sénior
 
Inscription : juillet 2003
Messages : 3 459
Détails du profil
Informations forums :
Inscription : juillet 2003
Messages : 3 459
Points : 4 226
Points : 4 226
non.
:new est un préfixe qui fait référence à une colonne, pas à une concaténation de données, ou un groupe d'enreg, etc...
__________________
More Code : More Bugs. Less Code : Less Bugs
McM est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/04/2008, 21h32   #3
Membre habitué
 
Avatar de ruscov
 
Inscription : mars 2007
Messages : 134
Détails du profil
Informations personnelles :
Âge : 27
Localisation : Belgique

Informations forums :
Inscription : mars 2007
Messages : 134
Points : 145
Points : 145
Donc je n'ai pas accès à un record que j'insère directement sans passer par le nommage des colonnes puisque j'insère quand même tout le record?

C'est quand même dommage ça... J'aurais cru qu'Oracle fournirait un truc du genre. Bon ben tant pis... Je vais devoir m'amuser...

Merci quand même.
ruscov est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/04/2008, 10h29   #4
Membre habitué
 
Avatar de ruscov
 
Inscription : mars 2007
Messages : 134
Détails du profil
Informations personnelles :
Âge : 27
Localisation : Belgique

Informations forums :
Inscription : mars 2007
Messages : 134
Points : 145
Points : 145
Bon alors j'ai trouvé une solution : un petit script pour créer ma requête en PL/SQL, comme ça pas besoin d'écrire à la main tous les champs.... Pour ceux que ca interesse je le met ici.

Je crée une table temporaire qui va accueillir ma requête.

Code ORACLE :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 
-- On crée la table temporaire qui va contenir les requêtes
CREATE TABLE temp_table_sql (sqlval varchar2(4000));
 
-- La procédure
DECLARE
 
cursor c_column IS
    SELECT column_name,rownum FROM user_TAB_COLUMNS uc WHERE table_name='INSCRIPTION';
 
str varchar2(4000);
i number(2);
 
BEGIN
 
str := 'INSERT INTO TEMP_INSCRIPTION (';
i := 0;
FOR rec IN c_column
LOOP
    IF i = 0 THEN
       str:=str ||REC.column_name;
    ELSE
        str:=str||', '||REC.column_name;
    END IF;    
    i := i+1;
END LOOP;
str:=str||') VALUES ( ';
i := 0;
FOR rec IN c_column
LOOP
    IF i = 0 THEN
       str:=str||' :new.'||REC.column_name;
    ELSE
        str:=str||', :new.'||REC.column_name;
    END IF;    
    i := i+1;
END LOOP;
 
str:=str||');';
INSERT INTO temp_table_sql VALUES (str);
END;
/
 
commit;

Et le tour est joué! J'ai ma requête INSERT INTO qui copie mon record NEW dans ma table temporaire!
ruscov est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/04/2008, 10h54   #5
McM
Expert Confirmé Sénior
 
Inscription : juillet 2003
Messages : 3 459
Détails du profil
Informations forums :
Inscription : juillet 2003
Messages : 3 459
Points : 4 226
Points : 4 226
Houla la !! C'est pas du tout optimisé !

Bon, tu fais 2 fois la même boucle.
Prends 2 variables (1 pour le INSERT, 1 pour le VALUES) et en 1 passe du curseur tu te crées les 2 ordres que tu concatènes ensuite.

En fait je suppose que tu ne le fais qu'une fois, donc ça va, je croyais que c'était dans le trigger.
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
DECLARE
 
CURSOR c_column IS
    SELECT column_name,ROWNUM FROM user_TAB_COLUMNS uc WHERE table_name='INSCRIPTION';
 
str1 VARCHAR2(4000);
str2 VARCHAR2(2000);
i NUMBER;
 
BEGIN
 
i := 0;
FOR rec IN c_column
LOOP
    IF i = 0 THEN
       str1 := str1 || REC.column_name;
       str2 := str2 ||':new.'|| REC.column_name;
    ELSE
       str1:= str1||', '||REC.column_name;
       str2 := str2 ||', :new.'|| REC.column_name;
    END IF;    
    i := 1;
END LOOP;
 
str1 := 'INSERT INTO TEMP_INSCRIPTION ('|| str1 ||') VALUES ('|| str2 ||');';
 
INSERT INTO temp_table_sql VALUES (str);
END;
/
__________________
More Code : More Bugs. Less Code : Less Bugs
McM est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/04/2008, 11h22   #6
Membre habitué
 
Avatar de ruscov
 
Inscription : mars 2007
Messages : 134
Détails du profil
Informations personnelles :
Âge : 27
Localisation : Belgique

Informations forums :
Inscription : mars 2007
Messages : 134
Points : 145
Points : 145
Merci beaucoup pour l'optimisation. Je ne suis pas encore très à l'aise avec PL/SQL.

Sinon, en effet je ne l'utilise qu'une seule fois pour créer ma requête. Après je mets ma requête tel quelle est générée dans mon trigger.

merci.
ruscov est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 19h48.


 
 
 
 
Partenaires

Hébergement Web