Précédent   Forum des professionnels en informatique > 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 Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 20/07/2011, 13h54   #1
Membre actif
 
Inscription : mai 2004
Messages : 725
Détails du profil
Informations forums :
Inscription : mai 2004
Messages : 725
Points : 193
Points : 193
Par défaut Ma commande PL/SQL ne donne ni erreurs ni update.

Bonjour,

J'ai réalisé un code en PL SQL pour faire des updates sur des tables.
Malheureusement lorsque j'execute mes commandes PL SQL il n'y a ni update ni erreur.

Pourtant il devrait y avoir une update en cas de succes.

Voici mes commandes PL SQL :
Y a t il des erreurs notables dans ces commandes ?
Je le lance depuis mon script sh :


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
30
31
32
33
34
35
36
 
sqlplus -s /nolog >/dev/NULL <<-EOF
connect $SCHEMA/$SCHEMAPW
 
SET trimspool ON
spool ./update_tables.log
 
whenever sqlerror exit 1;
 
DECLARE
 
CURSOR c_SAG_DATA IS
SELECT * FROM SAG_DATA_TEMP;
 
BEGIN
 
	FOR j IN c_SAG_DATA LOOP
 
	UPDATE document doc SET (doc.nda,doc.noip) =(SELECT j.nda,j.nip_actif
	FROM radiologie rad
	WHERE rad.id_document_lie = doc.id_document
	AND CONCAT(rad.ID_DEMANDE, rad.ID_EXAMEN) = j.s_aphp_reference_acte_rados);
 
	UPDATE radiologie rad SET (rad.uh_demandeuse,rad.nip) = (SELECT j.code_uh_demande,j.nip_actif
	WHERE CONCAT(rad.ID_DEMANDE, rad.ID_EXAMEN) = j.s_aphp_reference_acte_rados);
 
	END LOOP;
END;
COMMIT;
 
 
spool off
exit
EOF
 
echo "FIN"
Battosaiii est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/07/2011, 14h37   #2
Membre expérimenté
 
François
Inscription : février 2010
Messages : 305
Détails du profil
Informations personnelles :
Nom : François

Informations forums :
Inscription : février 2010
Messages : 305
Points : 535
Points : 535
Par défaut Tu ne me vois pas ?

Code :
1
2
[xxx ~]$ sqlplus xxx/xxx -s @tmp2 >/dev/NULL
[xxx ~]$ sqlplus xxx/xxx -s @tmp3 >/dev/NULL
Vous pouvez me dire lequel de ces deux scripts a fonctionne?
Je ne pense pas.

Un indice, l'un des deux scripts genere une erreur:
Code :
1
2
3
4
5
6
whenever sqlerror exit 1;
begin
UPDATE existe_pas SET n=2;
end;
/
commit;
Et l'autre est correct, avec un petit dbms_output pour le confirmer:
Code :
1
2
3
4
5
6
7
8
whenever sqlerror exit 1;
SET serveroutput ON
begin
dbms_output.put_line('a');
end;
/
commit;
 exit;


Enlevez donc le mode silence et la redirection de sortie. Je connais pas beaucoup de gens qui preferent faire du bricolage dans le noir, en regle generale on essaye de voir ce qu'on fait.
Ca vous aidera probablement a voir le soucis, qui est effectivement une erreur notable quand on souhaite executer un block PL/SQL.
Indice: Votre erreur est corrigee dans mes exemples.

Va falloir apprendre a déboguer, c'est du temps de gagner pour toute la vie
Rams7s est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 20/07/2011, 14h46   #3
Modérateur
 
Avatar de al1_24
 
Homme Alain
Ingénieur d'études décisionnel
Inscription : mai 2002
Messages : 4 445
Détails du profil
Informations personnelles :
Nom : Homme Alain
Âge : 51
Localisation : France, Val de Marne (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études décisionnel
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 4 445
Points : 7 532
Points : 7 532
Il est étonnant que tu n'aies pas d'erreur alors qu'il manque un FROM dans la sous-requête SELECT de la seconde requête UPDATE.

Par ailleurs, tes requêtes pourraient s'écrire plus simplement avec EXISTS.
Par exemple pour la première :
Code :
1
2
3
4
5
6
7
8
9
UPDATE  document doc 
SET     doc.nda     = j.nda
    ,   doc.noip    = j.nip_actif
WHERE   EXISTS
        (   SELECT  1
            FROM    radiologie rad
            WHERE   CONCAT(rad.id_demande, rad.id_examen) = j.s_aphp_reference_acte_rados
                AND rad.id_document_lie = doc.id_document
        );
__________________
Modérateur Langage SQL
Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
N'oubliez pas le bouton et pensez aux balises [code]
Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
al1_24 est déconnecté   Envoyer un message privé Réponse avec citation 11
Vieux 20/07/2011, 14h58   #4
Modérateur
 
Avatar de al1_24
 
Homme Alain
Ingénieur d'études décisionnel
Inscription : mai 2002
Messages : 4 445
Détails du profil
Informations personnelles :
Nom : Homme Alain
Âge : 51
Localisation : France, Val de Marne (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études décisionnel
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 4 445
Points : 7 532
Points : 7 532
Après relecture, la seconde n'a pas besoin de SELECT ni de FROM.
Code :
1
2
3
4
UPDATE  radiologie rad 
SET     rad.uh_demandeuse   = j.code_uh_demande
    ,   rad.nip             = j.nip_actif
WHERE   CONCAT(rad.ID_DEMANDE, rad.ID_EXAMEN) = j.s_aphp_reference_acte_rados;
Par ailleurs, ton expression de jointure sur CONCAT(rad.ID_DEMANDE, rad.ID_EXAMEN) = j.s_aphp_reference_acte_rados risque de ne pas être très performante si tu as de nombreux enregistrements.
Si tu as un index sur rad.ID_DEMANDE, rad.ID_EXAMEN, tu as plus intérêt à découper j.s_aphp_reference_acte_rados et faire une jointure sur rad.ID_DEMANDE = SUBSTR(j.s_aphp_reference_acte_rados, 1, ?) AND rad.ID_EXAMEN = SUBSTR(j.s_aphp_reference_acte_rados, ? + 1)
__________________
Modérateur Langage SQL
Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
N'oubliez pas le bouton et pensez aux balises [code]
Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
al1_24 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 20/07/2011, 16h37   #5
Membre actif
 
Inscription : mai 2004
Messages : 725
Détails du profil
Informations forums :
Inscription : mai 2004
Messages : 725
Points : 193
Points : 193
Merci pour ces réponses rapides.

Rams7s :

J'ai modifié mon script pour rajouter des logs comme dans ton exemple. Malgré tout il n'y a aucune différence car je n'observe rien dans les logs .

Voici comment j'ai modifié le script :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 
sqlplus -s /nolog >/dev/NULL <<-EOF
connect $SCHEMA/$SCHEMAPW
 
SET trimspool ON
spool ./update_tables.log
 
whenever sqlerror exit 1;
SET serveroutput ON
 
DECLARE
 
CURSOR c_SAG_DATA IS
SELECT * FROM SAG_DATA_TEMP;
 
BEGIN
dbms_output.put_line('BEGIN UPDATE SAG');
 
    FOR j IN c_SAG_DATA LOOP
 
..... même code que précédemment ici
J'ai rajouté SET serveroutput ON et aussi dbms_output.put_line('BEGIN UPDATE SAG');. Mais dans les logs je n'observe toujours rien. Quel erreur ai je pu commettre ?


al1_24 :

Je pense que je vais chercher à optimiser ces requetes comme tu las fait.
Mais pour l'instant ma requete ne marche pas. Je vais trouver d'abord un moyen de faire marcher ces requetes; As tu remarquer des anomalies dans ces requetes ?

Merci

Merci
Battosaiii est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/07/2011, 17h14   #6
Membre expérimenté
 
François
Inscription : février 2010
Messages : 305
Détails du profil
Informations personnelles :
Nom : François

Informations forums :
Inscription : février 2010
Messages : 305
Points : 535
Points : 535
Par défaut Yapakomprendre

Ben j'ai du comprendre de travers.

Ou alors, vous ne voulez pas lancer sqlplus "normalement"? Sans faire de redirection. Aussi loin que je sache, faire une redirection dans /dev/null ca revient a dire 'jette a la poubelle tout ce qui devrait apparaitre sur mon ecran'
Code :
1
2
3
4
5
[xxx ~]$ echo "toto" >/dev/NULL
[xxx ~]$ echo "toto" >./tmp
[xxx ~]$ cat /dev/NULL
[xxx ~]$ cat ./tmp
toto
Je reprends mes exemples de ce matin, sans faire la redirection dans la grosse poubelle et on voit si on peut obtenir des informations, sur qui de mes scripts tmp2 et tmp3 fonctionne:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[xxx ~]$ sqlplus -s xxx/xxx @tmp2
UPDATE existe_pas SET n=2;
       *
ERROR at line 2:
ORA-06550: line 2, COLUMN 8:
PL/SQL: ORA-00942: TABLE OR VIEW does NOT exist
ORA-06550: line 2, COLUMN 1:
PL/SQL: SQL Statement ignored
 
 
[xxx ~]$ sqlplus -s xxx/xxx @tmp3
a
 
PL/SQL procedure successfully completed.
 
 
Commit complete.
 
[xxx ~]$ echo "toto" >/dev/NULL
Ah ben oui, tmp2 essaye de toucher a une table qui n'existe pas (quel nom bien choisi!). Et on a meme la ligne ou ca ne fonctionne pas.
Note: La ligne, c'est la ligne du block PL/SQL, c'est a dire apres le begin, c'est pour ca que dans mon message de 14h37, ca va correspondre a la ligne 3.

Maintenant, a mon humble avis, si vous lancez
Code :
sqlplus -s xxx/xxx @monscript
vous allez obtenir une ligne vide sans rien, toujours aps tres pratique.
Enlevez l'option -s quand vous lancez SQL*Plus. De la, vous devriez avoir un petit numero qui s'incremente petit a petit. Avec eventuellement si vous trouvez le caractere magique et si je me base sur votre premier script un message d'erreur
Code :
PLS-00103: Encoutered the symbol "COMMIT"
Si c'est bien ca, vu que vous avez la ligne, vous devriez trouver ce que je soupconne etre l'erreur. Et apres il n'y a plus qu'a noter la reponse ici pour que ca serve a quelqu'un d'autre, et mettre le sujet en resolu.


PS: Si il n'y a aucun rapport avec la redirection de sqlplus, je suis desole pour la perte de temps.
Rams7s est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 25/07/2011, 12h12   #7
Membre actif
 
Inscription : mai 2004
Messages : 725
Détails du profil
Informations forums :
Inscription : mai 2004
Messages : 725
Points : 193
Points : 193
Merci Rams7s de ta réponse

J'ai modifié la commande sql plus pour obtenir des logs :
Code :
1
2
 
sqlplus $SCHEMA/$SCHEMAPW >./update_nda_sqlplus.log <<-EOF
J'obtiens les logs suivants :


Je ne comprend pas pourquoi il incremente 29 fois alors que dans ma table il y a 6 elements dans la table SAG_DATA_TEMP.

Comment interpréter ce résultat ?
Citation:

SQL*Plus: Release 9.2.0.6.0 - Production on Lu Jul 25 12:06:01 2011

Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.


Connecté à :
Oracle9i Enterprise Edition Release 9.2.0.6.0 - 64bit Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.6.0 - Production

SQL> Connecté.
SQL> SQL> SQL> SQL> SQL> SQL> SQL> SQL> 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 Déconnecté de Oracle9i Enterprise Edition Release 9.2.0.6.0 - 64bit Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.6.0 - Production
Battosaiii est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/07/2011, 17h30   #8
Membre actif
 
Inscription : mai 2004
Messages : 725
Détails du profil
Informations forums :
Inscription : mai 2004
Messages : 725
Points : 193
Points : 193
J'ai simplifié ma commande sql mais le script ne semble jamais finir.
Pourtant SAG_DATA_TEMP ne contient que 6 elements. Pourquoi cette commande ne semble jamais finir ?

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
 
 
DECLARE
 
CURSOR c_SAG_DATA IS
SELECT * FROM SAG_DATA_TEMP;
 
BEGIN
dbms_output.put_line('BEGIN UPDATE SAG');
 
    FOR j IN c_SAG_DATA LOOP
 
	UPDATE document doc SET (doc.nda,doc.noip) =(SELECT j.nda,j.nip_actif
    FROM radiologie rad
    WHERE rad.id_document_lie = doc.id_document
    AND CONCAT(rad.ID_DEMANDE, rad.ID_EXAMEN) = j.s_aphp_reference_acte_rados);
 
 
    END LOOP;
 
 
END;
/
exit;
Battosaiii est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/07/2011, 18h01   #9
Modérateur
 
Avatar de al1_24
 
Homme Alain
Ingénieur d'études décisionnel
Inscription : mai 2002
Messages : 4 445
Détails du profil
Informations personnelles :
Nom : Homme Alain
Âge : 51
Localisation : France, Val de Marne (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études décisionnel
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 4 445
Points : 7 532
Points : 7 532
Qu'est-ce que SAG_DATA_TEMP ?
Une table ou une vue ?
Si c'est une vue, sur quelles tables porte-t-elle ?
__________________
Modérateur Langage SQL
Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
N'oubliez pas le bouton et pensez aux balises [code]
Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
al1_24 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 25/07/2011, 18h30   #10
Membre Expert
 
Avatar de pacmann
 
Homme Pacman Pacman
Business analyst
Inscription : juin 2004
Messages : 1 417
Détails du profil
Informations personnelles :
Nom : Homme Pacman Pacman
Âge : 31
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Business analyst
Secteur : Finance

Informations forums :
Inscription : juin 2004
Messages : 1 417
Points : 2 309
Points : 2 309
Salut !

L'écriture d'Al1 n'est pas seulement une optimisation : elle produit un autre résultat !

En fait, quand tu fais :
Code :
1
2
3
 
UPDATE tatable 
SET (col1, col2) = (SELECT ...FROM ... WHERE..)
=> pour les lignes de tatable qui ne répondent pas aux critères de la requête entre parenthèses, il te colle des NULL, alors que dans la version d'al1 ce n'est pas le cas.

Du coup, tu mets toute ta table documents à jour, ce qui en fonction de sa taille peut être long, et encore plus s'il y a des locks qui trainent...
__________________

(c'est ma photo)
Paku, Paku !
Pour les jeunes incultes : non, je ne suis pas un pokémon...

Le pacblog : http://pacmann.over-blog.com/
pacmann est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 26/07/2011, 08h34   #11
Membre actif
 
Inscription : mai 2004
Messages : 725
Détails du profil
Informations forums :
Inscription : mai 2004
Messages : 725
Points : 193
Points : 193
Merci de vos réponses.

al1_24 : SAG_DATA_TEMP est une table.

pacmann : J'ai pas l'impression que la table document a été changé même si c'est dur de vérifier tous les elements : il y en a 140 000 elements dans la table document !!!

De plus la solution d'al1_24 avec le Exists est une solution que j'employais avant. Cette solution marche. C'est une requete tres longue a executer. Elle prend plusieurs jours sur des tables tres importantes(des tables de + de 100 000 elements). C'est pourquoi je cherche une solution alternative a la solution avec le EXISTS.

Avant j'utilisais :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
 
 
UPDATE document doc
   SET (doc.nda,doc.noip) = (SELECT sda.nda,sda.nip_actif
                    FROM SAG_DATA_TEMP sda
                         INNER JOIN radiologie rad
                           ON CONCAT(rad.ID_DEMANDE, rad.ID_EXAMEN) = sda.s_aphp_reference_acte_rados
                   WHERE rad.id_document_lie = doc.id_document)
 WHERE EXISTS (SELECT NULL
                 FROM SAG_DATA_TEMP sda
                      INNER JOIN radiologie rad
                        ON CONCAT(rad.ID_DEMANDE, rad.ID_EXAMEN) = sda.s_aphp_reference_acte_rados
                WHERE rad.id_document_lie = doc.id_document);
Il faut que je fasse une update sur la table Document a partir de la table SAG_DATA_TEMP. C'est pourquoi j'utilise un cursor pour accelerer le traitement. Quel autre solution suggere tu pour accelerer le traitement ?

Merci
Battosaiii est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/07/2011, 09h57   #12
Membre Expert
 
Avatar de pacmann
 
Homme Pacman Pacman
Business analyst
Inscription : juin 2004
Messages : 1 417
Détails du profil
Informations personnelles :
Nom : Homme Pacman Pacman
Âge : 31
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Business analyst
Secteur : Finance

Informations forums :
Inscription : juin 2004
Messages : 1 417
Points : 2 309
Points : 2 309
En fait, si ta requête ne se termine pas, tu ne peux pas vérifier (tant que tu ne commit pas, tu ne verras pas le résultat à partir d'une autre session !)

Question perfs, plusieurs jours pour l'update, ce n'est pas normal...

Les questions qu'il faut se poser :
=> Combien d'éléments doivent être mis à jour dans la table document ?
=> Quel est le plan d'exécution ?
En fonction de ces deux premiers points, tu pourras voir s'il faut peut être poser un index au bon endroit

Et si tu es en 10g ou plus, tu peux utiliser MERGE (qui permet de faire le filtre et l'update en un coup)
__________________

(c'est ma photo)
Paku, Paku !
Pour les jeunes incultes : non, je ne suis pas un pokémon...

Le pacblog : http://pacmann.over-blog.com/
pacmann est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 27/07/2011, 14h16   #13
Membre actif
 
Inscription : mai 2004
Messages : 725
Détails du profil
Informations forums :
Inscription : mai 2004
Messages : 725
Points : 193
Points : 193
Merci de vos reponses.

Ma question original a été résolu car il n'y a plus d'erreurs . Les requetes sql s'executent correctement. par contre les requetes sql n'update pas correctement mais cela est un autre probleme.
Battosaiii 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 04h42.


 
 
 
 
Partenaires

Hébergement Web