Précédent   Forum du club des développeurs et IT Pro > Bases de données > Oracle > PL/SQL
PL/SQL Forum d'entraide sur le PL/SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 03/01/2013, 11h39   #1
OTMANE ait
Invité de passage
 
Homme
Administrateur de base de données
Inscription : janvier 2013
Messages : 8
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Maroc

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : Industrie

Informations forums :
Inscription : janvier 2013
Messages : 8
Points : 0
Points : 0
Par défaut [9i] Trigger insertion d'un XML dans BLOB

Bonjour,

Dans un environnement 9i,je voudrais créer un trigger qui permet d'alimenter un champs BLOB par un contenu xml après son insertion dans un champ de type XMLType pour cette raison dans ma base.

Ma table :
Code :
1
2
3
4
CREATE TABLE SYNCRODV.t_xml ( 
 transid number NOT NULL, 
 DATA blob ,
 xml_data XMLTYPE);
La fonction qui permet de transférer un champ CLOB en BLOB:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
CREATE OR REPLACE FUNCTION SYNCRODV.c2b( c IN CLOB ) RETURN BLOB
-- typecasts CLOB to BLOB (binary conversion)
IS
pos PLS_INTEGER := 1;
buffer RAW( 32767 );
res BLOB;
lob_len PLS_INTEGER := DBMS_LOB.getLength( c );
BEGIN
DBMS_LOB.createTemporary( res, TRUE );
DBMS_LOB.OPEN( res, DBMS_LOB.LOB_ReadWrite );
LOOP
buffer := UTL_RAW.cast_to_raw( DBMS_LOB.SUBSTR( c, 16000, pos ) );
IF UTL_RAW.LENGTH( buffer ) > 0 THEN
DBMS_LOB.writeAppend( res, UTL_RAW.LENGTH( buffer ), buffer );
END IF;
pos := pos + 16000;
EXIT WHEN pos > lob_len;
END LOOP;
RETURN res; -- res is OPEN here
END c2b;
/
Le trigger qui permet d'alimenter le blob dès que le champ xml est inséré dans la même ligne :
Code :
1
2
3
4
5
6
7
8
CREATE TRIGGER SYNCRODV.TRIG_XML_BLOB
    after INSERT ON SYNCRODV.t_xml
    FOR each row
    declare
    begin
 
      UPDATE SYNCRODV.t_xml t SET DATA=syncrodv.c2B(:new.xml_data.getClobVal());
    end;
Mais lorsque je simule une insertion dans ma table exemple :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
INSERT INTO SYNCRODV.t_xml (transid,xml_data) VALUES
(1,
XMLTYPE.CREATEXML('<?xml version="1.0"
encoding="ISO-8859-1"?>
<compagnie>
<comp>AC</comp>
<pilotes>
<pilote brevet="PL-3">
<nom>G. Diffis</nom>
<salaire>5000</salaire>
</pilote>
<pilote brevet="PL-4">
<nom>S. Lacombe</nom>
</pilote>
</pilotes>
<nomComp>Castanet Lines</nomComp>
</compagnie>')
);
commit;
Il me donne toujours le message suivant :
Citation:
Error at line 1
ORA-04091: table SYNCRODV.T_XML en mutation, déclencheur/fonction ne peut la voir
ORA-06512: à "SYNCRODV.TRIG_XML_BLOB", ligne 4
ORA-04088: erreur lors d'exécution du déclencheur 'SYNCRODV.TRIG_XML_BLOB'
Je suis bloqué merci de votre aide.
OTMANE ait est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/01/2013, 14h18   #2
mnitu
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 4 108
Détails du profil
Informations personnelles :
Nom : Homme Marius Nitu
Localisation : France, Marne (Champagne Ardenne)

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : octobre 2007
Messages : 4 108
Points : 8 006
Points : 8 006
Changez votre trigger en
Code :
1
2
3
4
5
6
7
 
CREATE OR REPLACE TRIGGER TRIG_XML_BLOB
before INSERT ON t_xml
FOR each row
begin
  :new.DATA := c2B(:new.xml_data.getClobVal());
end;
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 03/01/2013, 14h32   #3
Waldar
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 6 278
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 35
Localisation : France, Essonne (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : septembre 2008
Messages : 6 278
Points : 13 566
Points : 13 566
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
En plus de la réponse de mnitu, je me questionne sur l'intérêt de stocker un XML dans un BLOB plutôt qu'un CLOB.
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/01/2013, 16h57   #4
OTMANE ait
Invité de passage
 
Homme
Administrateur de base de données
Inscription : janvier 2013
Messages : 8
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Maroc

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : Industrie

Informations forums :
Inscription : janvier 2013
Messages : 8
Points : 0
Points : 0
merci mille fois mnitu le trigger marche bien ,
pour la remarque Waldar c'est une exigence applicatif,
on travaille sur l’interfaçage entre deux applications,la deuxième application a besoin de donnée sous forme de BLOB
OTMANE ait est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/01/2013, 10h40   #5
OTMANE ait
Invité de passage
 
Homme
Administrateur de base de données
Inscription : janvier 2013
Messages : 8
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Maroc

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : Industrie

Informations forums :
Inscription : janvier 2013
Messages : 8
Points : 0
Points : 0
une autre demande svp,
la deuxième étape est que je dois transférer ces données vers une autre table dans une autre BD2 11g via le même trigger,
donc j'ai créé un DB_link dans la première BD1 qui pointe vers BD2:

Code :
1
2
3
4
CREATE DATABASE LINK "DB2_link"
 CONNECT TO USER
 IDENTIFIED BY ****
 USING 'DB2';
et j'ai modifié mon trigger:
Code :
1
2
3
4
5
6
7
CREATE OR REPLACE TRIGGER TRIG_XML_BLOB
before INSERT ON t_xml
FOR each row
begin
  :new.DATA := c2B(:new.xml_data.getClobVal());
  INSERT INTO USER.T_TESYS_IN@DB2_link (transid,DATA) VALUES (:new.transid ,:new.DATA);
end;

lorsque je fais un insert il me donne l'erreur suivante:

Citation:
Error at line 1
ORA-22927: le pointeur de LOB indiqué n'est pas valide
ORA-02063: précédant line de DB2_LINK
ORA-06512: à "SYNCRODV.TRIG_XML_BLOB", ligne 4
ORA-04088: erreur lors d'exécution du déclencheur 'SYNCRODV.TRIG_XML_BLOB'
merci d'avance pour votre réponse
OTMANE ait est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/01/2013, 11h19   #6
mnitu
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 4 108
Détails du profil
Informations personnelles :
Nom : Homme Marius Nitu
Localisation : France, Marne (Champagne Ardenne)

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : octobre 2007
Messages : 4 108
Points : 8 006
Points : 8 006
Lisez ce lien.
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 04/01/2013, 16h58   #7
OTMANE ait
Invité de passage
 
Homme
Administrateur de base de données
Inscription : janvier 2013
Messages : 8
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Maroc

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : Industrie

Informations forums :
Inscription : janvier 2013
Messages : 8
Points : 0
Points : 0
Dans cette exemple il utilise bfile ,est ce que je suis obligé de les utilisés,
pourtant j'ai deja mon blob charger dans le champ de la table t_xml(DB1)
je voudrais juste le transferer dans la base DB2, pourtant si je fais l’opération manuellement sans passé par le trigger ça marche,

sinon j'ai testé un autre truc 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
CREATE OR REPLACE TRIGGER TRIG_XML_BLOB
before INSERT ON t_xml
FOR each row
    declare
   Lob_loc    BLOB;
   Buffer     RAW(32767);
   Amount     Binary_integer := 32767;
 
begin
 
     :new.DATA := SYNCRODV.c2B(:new.xml_data.getClobVal());
 
    -- On insére la ligne avec un blob vide dont on récupère le pointeur
INSERT INTO USER.T_TESYS_IN@DB2_link (transid,DATA) VALUES (:new.transid ,empty_blob()) RETURNING DATA INTO Lob_loc;
 
        DBMS_LOB.OPEN (Lob_loc, DBMS_LOB.LOB_READWRITE);
   /* Append the data from the buffer to the end of the LOB: */
   DBMS_LOB.WRITEAPPEND(Lob_loc, Amount, :new.DATA);
   /* Closing the LOB is mandatory if you have opened it: */
   DBMS_LOB.CLOSE(Lob_loc);
 
    end;
/
mais erreur:

Citation:
ORA-22992: impossible d'utiliser les indicateurs d'emplacement LOB sélectionnés dans des tables distantes
ORA-06512: à "SYNCRODV.TRIG_XML_BLOB", ligne 10
ORA-04088: erreur lors d'exécution du déclencheur 'SYNCRODV.TRIG_XML_BLOB'
OTMANE ait est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/01/2013, 17h11   #8
mnitu
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 4 108
Détails du profil
Informations personnelles :
Nom : Homme Marius Nitu
Localisation : France, Marne (Champagne Ardenne)

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : octobre 2007
Messages : 4 108
Points : 8 006
Points : 8 006
C'était pour la phrase:
Citation:
You cannot accomplish this via a trigger in real time, the data is not there.
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 09/01/2013, 14h31   #9
OTMANE ait
Invité de passage
 
Homme
Administrateur de base de données
Inscription : janvier 2013
Messages : 8
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Maroc

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : Industrie

Informations forums :
Inscription : janvier 2013
Messages : 8
Points : 0
Points : 0
pour remédier nous avons opté de stocker le ficher xml dans une colonne de type LONG (et aussi pour des contrainte d'output ERP ) , mais est ce que on peut utiliser une variable LONG dans un trigger,
car j'ai toujours l'erreur :ORA-04093
OTMANE ait est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/01/2013, 14h34   #10
mnitu
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 4 108
Détails du profil
Informations personnelles :
Nom : Homme Marius Nitu
Localisation : France, Marne (Champagne Ardenne)

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : octobre 2007
Messages : 4 108
Points : 8 006
Points : 8 006
Oubliez le type LONG! Faite comme si il n’existe pas!
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/01/2013, 15h13   #11
OTMANE ait
Invité de passage
 
Homme
Administrateur de base de données
Inscription : janvier 2013
Messages : 8
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Maroc

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : Industrie

Informations forums :
Inscription : janvier 2013
Messages : 8
Points : 0
Points : 0
j'ai retrouvé un lien:
https://forums.oracle.com/forums/thr...hreadID=856638
je l'ai testé mais ça ne marche pas , il n'arrive pas à retrouver le db_link:
pourtant je l'ai créé:
message d'erreur:
Citation:
ORA-12546: TNS : autorisation refusée
ORA-06512: à "T_TRG", ligne 18
ORA-04088: erreur lors d'exécution du déclencheur 'T_TRG'
la création du db_link:
Code :
1
2
CREATE DATABASE LINK LOOPBACK
 USING '(description=(address=(protocol=beq)(program=/u01/app/oracle/product/9.2.0.1.0)))';
======
mon $ORACLE_HOME=/u01/app/oracle/product/9.2.0.1.0
OTMANE ait est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


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


 
 
 
 
Partenaires

Hébergement Web