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 05/09/2011, 17h15   #1
Invité de passage
 
Inscription : mai 2008
Messages : 8
Détails du profil
Informations forums :
Inscription : mai 2008
Messages : 8
Points : 1
Points : 1
Par défaut Remplir plusieurs variables ROWTYPE en 1 select

Bonjour à tous,

Sous Oracle 10g, je n'arrive pas à exécuter ceci :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
CREATE OR REPLACE PROCEDURE TEST AS
  A  TABLE_A%ROWTYPE;
  B  TABLE_B%ROWTYPE;
  C  TABLE_C%ROWTYPE;
BEGIN
 
  SELECT 
     TABLE_A.* INTO A , 
     TABLE_B.* INTO B , 
     TABLE_C.* INTO C
  FROM TABLE_A
  INNER JOIN TABLE_B  .... [blablabla] WHERE [blablabla] ;
 
END TEST;
Je suis peut être trop optimiste, est-ce possible ?

Pour le moment, j'ai l'erreur suivante :

Code :
Error(10,3): PLS-00494: contrainte non prise en charge dans plusieurs cibles de type enregistrement
Merci à tous pour votre aide !
Maxou59760 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/09/2011, 17h50   #2
Membre expérimenté
 
François
Inscription : février 2010
Messages : 306
Détails du profil
Informations personnelles :
Nom : François

Informations forums :
Inscription : février 2010
Messages : 306
Points : 536
Points : 536
Par défaut Le prince charmant

En utilisant un curseur, vous pouvez avoir le type de vos reves
(non non, pas de jeu de mot foireux)

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
DROP TABLE tmp1;
DROP TABLE tmp2;
CREATE TABLE tmp1 (n1 number, pad1 varchar2(50));
CREATE TABLE tmp2 (n2 number, pad2 varchar2(50));
 
INSERT INTO tmp1 VALUES (1,'xx');
INSERT INTO tmp1 VALUES (2,'xx');
INSERT INTO tmp1 VALUES (3,'xx');
INSERT INTO tmp1 VALUES (4,'xx');
 
INSERT INTO tmp2 VALUES (1,'xx');
INSERT INTO tmp2 VALUES (2,'xx');
INSERT INTO tmp2 VALUES (4,'xx');
INSERT INTO tmp2 VALUES (6,'xx');
 
commit;
 
CREATE OR REPLACE procedure tmp_proc IS
   cursor l_cur IS SELECT tmp1.*, tmp2.* FROM tmp1,tmp2 WHERE n1=n2;
   my_var2 l_cur%rowtype;
begin
   FOR my_var IN l_cur loop
      dbms_output.put_line(my_var.n1||' '||my_var.n2);
      my_var2:=my_var;
   end loop;
   --Ou on utilise une variable pour stocker so on ne veut aps de la boucle for
   dbms_output.put_line(my_var2.pad2);
end;
/
SHOW errors
exec tmp_proc;
(Perso, je prefere large le curseur implicite par contre)
Rams7s est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/09/2011, 11h56   #3
Membre Expert
 
Inscription : août 2008
Messages : 1 271
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 1 271
Points : 1 929
Points : 1 929
Par contre dbms_output c'est quand même rarement utile, regarde également Fonction qui retourne un curseur si besoin
skuatamad est déconnecté   Envoyer un message privé Réponse avec citation 01
Vieux 12/09/2011, 11h38   #4
Invité de passage
 
Inscription : mai 2008
Messages : 8
Détails du profil
Informations forums :
Inscription : mai 2008
Messages : 8
Points : 1
Points : 1
Bonjour,
Merci pour vos réponses

Par contre ce n'est pas exactement le but recherché, si j'adapte le code avec le curseur ci-dessus, j'obtiens :

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
procedure tmp_proc IS
   cursor l_cur IS SELECT tmp1.*, tmp2.* FROM tmp1,tmp2 WHERE n1=n2;
   my_var2 l_cur%rowtype;
 
   -- Contenu de mes tables en mémoire
   v_tmp1 tmp1%ROWTYPE;
   v_tmp2 tmp2%ROWTYPE;
begin
   FOR my_var IN l_cur loop
      -- Table 1 
      v_tmp1.n1 := my_var.n1;
      v_tmp1.pad1 := my_var.pad1;
 
      -- Table 2 
      v_tmp2.n2 := my_var.n2;
      v_tmp2.pad2 := my_var.pad2;
   end loop;
   -- A ce moment là, mes ROWTYPE sont remplis, je peux les passer en paramètre, jouer avec ...
end;
Pour remplir mes 2 ROWTYPE (le but étant d'avoir une structure en mémoire) je dois mapper les champs 1 à 1, pas pratique...

Je peux remplir les ROWTYPE 1 à un 1 mais là aussi pas pratique ...
Code :
1
2
3
 
SELECT * FROM tmp1 INTO v_tmp1  WHERE ...
SELECT * FROM tmp2 INTO v_tmp2 WHERE ...

En fait je recherche la solution miracle, rapide et surtout lisible mais peut être qu'elle n'existe pas.

En tout cas merci pour ces premiers éléments de réponse
Maxou59760 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/09/2011, 22h47   #5
Membre Expert
 
Inscription : août 2008
Messages : 1 271
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 1 271
Points : 1 929
Points : 1 929
Est ce que ça correspond à ton besoin ?
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CREATE OR REPLACE procedure tmp_proc IS
  cursor l_cur IS SELECT tmp1.*, tmp2.* FROM tmp1,tmp2 WHERE n1=n2;
  TYPE TYPE_MY_VAR2 IS TABLE OF l_cur%rowtype;
  my_var2 TYPE_MY_VAR2;
begin
   open l_cur;
    loop fetch l_cur bulk collect INTO my_var2 LIMIT 500;
      -- A ce moment là, mes ROWTYPE sont remplis, je peux les passer en paramètre, jouer avec ...
      FOR i IN my_var2.first..my_var2.last loop
	dbms_output.put_line (my_var2(i).pad1 || ' ' || my_var2(i).pad2);
      end loop;
    Exit When l_cur%NOTFOUND ;
   end loop;   
end;
/
Regarde aussi Collections et enregistrements.
skuatamad est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/09/2011, 12h16   #6
Membre expérimenté
 
François
Inscription : février 2010
Messages : 306
Détails du profil
Informations personnelles :
Nom : François

Informations forums :
Inscription : février 2010
Messages : 306
Points : 536
Points : 536
La seule partie interessante de l'exemple qui suit, c'est que dans le select on cree des objets directement. Ce sont des objets cree en base. Et ensuite, on assigne les objets grace au fetch into qui prends plusieurs variables.
Visiblement, avec des records PLSQL, ca ne fonctionne pas.
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
37
38
39
40
41
DROP TABLE tmp1;
DROP TABLE tmp2;
 
CREATE TABLE tmp1 (n1 number, pad1 varchar2(40));
CREATE TABLE tmp2 (n2 number, pad2 varchar2(40));
 
INSERT INTO tmp1 VALUES (1,'x');
INSERT INTO tmp1 VALUES (2,'x');
INSERT INTO tmp1 VALUES (3,'x');
INSERT INTO tmp1 VALUES (4,'x');
INSERT INTO tmp1 VALUES (5,'x');
INSERT INTO tmp1 VALUES (6,'x');
 
INSERT INTO tmp2 VALUES (1,'y');
INSERT INTO tmp2 VALUES (3,'y');
INSERT INTO tmp2 VALUES (5,'y');
INSERT INTO tmp2 VALUES (7,'y');
 
commit;
 
CREATE OR REPLACE type tmp_type1 AS object (n1 number, pad1 varchar2(40));
/
CREATE OR REPLACE type tmp_type2 AS object (n2 number, pad2 varchar2(40));
/
 
declare
   type tmp_type1_tt IS TABLE of tmp_type1;
   type tmp_type2_tt IS TABLE of tmp_type2;
   a1 tmp_type1_tt;
   a2 tmp_type2_tt;
begin
   SELECT tmp_type1(tmp1.n1,tmp1.pad1),tmp_type2(tmp2.n2,tmp2.pad2) bulk collect INTO a1,a2 FROM tmp1,tmp2 WHERE n1=n2;
   dbms_output.put_line(a1.count||' '||a2.count);
   FOR i IN a1.first..a1.last loop
      dbms_output.put_line(a1(i).n1||': '||a1(i).pad1);
   end loop;
   dbms_output.put_line('.');
   FOR i IN a2.first..a2.last loop
      dbms_output.put_line(a2(i).n2||': '||a2(i).pad2);
   end loop;
end;
Et qui donne:
Code :
1
2
3
4
5
6
7
8
9
10
3 3
1: x
3: x
5: x
.
1: y
3: y
5: y
 
PL/SQL procedure successfully completed.
Rams7s est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 17h14.


 
 
 
 
Partenaires

Hébergement Web