Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2228 connectés 

 


Dernière réponse
Sujet : sql: multiselect en un seul...
Fred999 Pas de problème. C'était quand même assez tordu ton truc, on ne me l'avait jamais fait faire, j'aurai au moins appris quelque chose aujourd'hui!

Votre réponse
Nom d'utilisateur    Pour poster, vous devez être inscrit sur ce forum .... si ce n'est pas le cas, cliquez ici !
Le ton de votre message                        
                       
Votre réponse


[b][i][u][strike][spoiler][fixed][cpp][url][email][img][*]   
 
   [quote]
 

Options

 
Vous avez perdu votre mot de passe ?


Vue Rapide de la discussion
Fred999 Pas de problème. C'était quand même assez tordu ton truc, on ne me l'avait jamais fait faire, j'aurai au moins appris quelque chose aujourd'hui!
wouatouwouatou Super ca marche impec ton script...
Un grand MERCI !!  
:jap::jap::jap::jap::jap::jap::jap::jap::jap::jap::jap::jap::jap:
 
P.S: voila le script final: (en transac.. désolé.. mais bon il marche :D )
 

drop table toto
GO
 
create table toto (
a numeric(10) identity primary key,
b numeric(10),
c varchar(20),
constraint fk_toto_toto foreign key (b) references toto(a)
)
GO
 
drop procedure sp_test_toto
go
 
create procedure sp_test_toto
  @tete numeric(10)
as
begin
 
create table #tmp_toto (    
           a numeric(10),    
           b numeric(10),    
           c varchar(20),    
           rang int    
);
 
declare @inCompteur int;
declare @inRang int;
 
select @inCompteur = 1,
       @inRang = 0    
 
/* Insertion initiale */    
insert #tmp_toto    
select    
       a,    
       b,    
       c,    
       @inRang    
from    
       toto  
where    
       a = @tete;
 
/* Insertions récursives */    
while ( @inCompteur != 0 )  
begin    
 
   insert #tmp_toto (a, b, c, rang)    
   select    
          t1.a,    
          t1.b,    
          t1.c,    
          @inRang + 1  
   from    
          toto  t1,    
          #tmp_toto t2    
   where    
          t1.a = t2.b    
   and    
          t2.rang = @inRang    
 
   select @inCompteur = @@rowcount  
   select @inRang = @inRang + 1    
 
end    
 
select * from #tmp_toto    
 
drop table #tmp_toto
 
end
go
 
wouatouwouatou si jai trouve merci :D
Fred999 Bin pour le mettre en proc stock... Tu n'as pas d'exemples de procs stockées à ton bureau? :??:
wouatouwouatou ps pour proc. stock. :D
Désolé, ce sont mes abreviations...

 

[edit]--Message édité par wouatouwouatou--[/edit]

Fred999 Si, ta condition est bonne fonctionnellement parlant, mais la syntaxe laissait fortement à désirer.
 
"mettre en ps"?????? :??:
 
Et si, il faut virer la table tempo. J'avais oublié.
wouatouwouatou ouais... en clair, elle sert a rien cette condition donc... :D
merci... au fait comment tu fait pour le mettre en ps ?
c koi la syntaxe ?
Pi fo pas dropper la table tmp ?
Fred999 OK... Deux manières différentes d'aborder le problème.
 
1. while (select count (*) from #tmp_toto where b is null and rang = @inRang - 1) = 0
C'est ce que tu veux faire : vérifier que toutes les lignes du rang max de la table #tmp_toto ne pointent sur rien : pas de suivantes.
 
2. While @inCompteur != 0
Tant qu'on trouve des lignes qui suivent...
wouatouwouatou bah.. en fait, c la condition de sortie de la boucle :D
 
while ( #tmp_toto.b is not null ) do ...
 
Car si la ligne trouvee ne pointe plus sur une ligne (donc b vaut null) alors i fo s'arreter la.
Fred999 create table #tmp_toto (  
           a numeric(10),  
           b numeric(10),  
           c varchar(20),  
           rang int  
)  
 
declare @inCompteur int  
declare @inRang int  
 
select @inCompteur = 1,  
       @inRang = 0  
 
/* Insertion initiale */  
insert #tmp_toto  
select  
       a,  
       b,  
       c,  
       @inRang  
from  
       toto  
where  
       a = 1  
 
/* Insertions récursives */  
while ( @inCompteur != 0 )
begin  
 
   if ( #tmp_toto.b is null ) then  
     exit;
   end if
 
J'avais pas vu cette ligne :D
if (#tmp_toto.b is null) Alors là... c'est du barbarisme!!!
Si tu veux vérifier un champ de la table #tmp_toto, il faut que tu fasses un if exists(). Mais tu veux faire quoi exactement?
 
ET LES AUTRES, VOUS Y AVEZ JETE UN OEIL AU SCRIPT?
 
Sinon, pour le reste, ça m'a l'air OK.

   insert #tmp_toto (a, b, c, rang)  
   select  
          t1.a,  
          t1.b,  
          t1.c,  
          @inRang + 1
   from  
          toto  t1,  
          #tmp_toto t2  
   where  
          t1.a = t2.b  
   and  
          t2.rang = @inRang  
 
   select @inCompteur = @@rowcount  
   select @inRang = @inRang + 1  
 
end  
 
select * from #tmp_toto  
 

Et à dans 10 minutes ;)
wouatouwouatou bon... ok pour inRang..
la ligne d'origine , i me la fo aussi :) donc ok aussi.
 
Pour la condition de sortie, tas raison... de toute maniere, il ne devrai y avoir kune seule ligne trouvee a la fois, du fait ke c la cle primaire.
 
Et le if... dans la boucle devrai normalement faire une sorte de  break;
 
Quant a la syntaxe... moi, jsais pas... car mon pl/sql est aussi bon ke mon transac voire pire :D
Donc apres tout ca je refait le script ki donne ( syntaxiquement fo :D ) :
 

create table #tmp_toto (  
           a numeric(10),  
           b numeric(10),  
           c varchar(20),  
           rang int  
)  
 
declare @inCompteur int  
declare @inRang int  
 
select @inCompteur = 1,  
       @inRang = 0  
 
/* Insertion initiale */  
insert #tmp_toto  
select  
       a,  
       b,  
       c,  
       @inRang  
from  
       toto  
where  
       a = 1  
 
/* Insertions récursives */  
while ( @inCompteur != 0 )
begin  
 
   if ( #tmp_toto.b is null ) then  
     exit;
   end if
 
   insert #tmp_toto (a, b, c, rang)  
   select  
          t1.a,  
          t1.b,  
          t1.c,  
          @inRang + 1
   from  
          toto  t1,  
          #tmp_toto t2  
   where  
          t1.a = t2.b  
   and  
          t2.rang = @inRang  
 
   select @inCompteur = @@rowcount  
   select @inRang = @inRang + 1  
 
end  
 
select * from #tmp_toto  
 
Fred999 [citation][nom]wouatouwouatou a écrit[/nom]
create table #tmp_toto (  
           a numeric(10),  
           b numeric(10),  
           c varchar(20),  
           rang int  
)  
 
declare @inCompteur int  
declare @inRang int  
 
select @inCompteur = 1,  
       @inRang = 0  
 
/* Insertion initiale */  
insert #tmp_toto  
select  
       a,  
       b,  
       c,  
       @inRang  
from  
       toto
where  
       a = 1  
 
Si tu veux la ligne d'origine, alors OK. Tu l'avais précisé?
 
/* Insertions récursives */  
while (@inRang < @inCompteur)  
begin  
 
   select @inRang = @inRang + 1  
 
Tu ne peux pas incrémenter le rang dès le début de la boucle... Au premier passage, tu n'auras que du rang 0 dans ta table tempo, et la requête va aller chercher les lignes de rang 1. Si j'avais fait un petit mic-mac sur l'incrémentation, ce n'était pas pour rien...
Ou alors, le 2e critère du WHERE devient t2.rang = @inRang - 1

 
De plus, donner comme critère de sortie de boucle @inRang < @inCompteur me paraît plus que douteux. Tu peux justifier?
 
   if ( #tmp_toto.b is not null ) then
 
   insert #tmp_toto (a, b, c, rang)  
   select  
          t1.a,  
          t1.b,  
          t1.c,  
          @inRang
   from  
          toto  t1,  
          #tmp_toto t2  
   where  
          t1.a = t2.b  
   and  
          t2.rang = @inRang  
 
   select count(*) into @inCompteur
   from #tmp_toto
 
La syntaxe PL-SQL n'est-clle pas select @inCompteur := count (*) ... ?
 
   end if
 
end  
 
select * from #tmp_toto  
 
 
Bon, après, tu mets ça en proc stock, tu compiles, et tu exécutes avec la commande @@nom_proc (si mes souvenirs sont bons)
wouatouwouatou Fred999> j'ai retouché un peu ton script... je pense ke kom ca il fait un peu mie ce e je veux... mais si tu (ou kkun) pouvais corriger ce serait cool... paske moi jsuis assez mediocre en sql :)

create table #tmp_toto (  
           a numeric(10),  
           b numeric(10),  
           c varchar(20),  
           rang int  
)  
 
declare @inCompteur int  
declare @inRang int  
 
select @inCompteur = 1,  
       @inRang = 0  
 
/* Insertion initiale */  
insert #tmp_toto  
select  
       a,  
       b,  
       c,  
       @inRang  
from  
       toto
where  
       a = 1  
 
/* Insertions récursives */  
while (@inRang < @inCompteur)  
begin  
 
   select @inRang = @inRang + 1  
 
   if ( #tmp_toto.b is not null ) then
 
   insert #tmp_toto (a, b, c, rang)  
   select  
          t1.a,  
          t1.b,  
          t1.c,  
          @inRang
   from  
          toto  t1,  
          #tmp_toto t2  
   where  
          t1.a = t2.b  
   and  
          t2.rang = @inRang  
 
   select count(*) into @inCompteur
 
   end if
 
from #tmp_toto
 
end  
 
select * from #tmp_toto  

 
Mais jsais toujours pas komment le transformer en pl/sql...
Mes souvenirs dans ce domaine me font defaut :D
Alors, si une ame charitable pouvait... :jap:
 
p.s: Comment kon fait pour mettre ce truc en proc. stock. et l'utiliser apres ?

 

[edit]--Message édité par wouatouwouatou--[/edit]

Fred999 Effectivement, il te faut une procédure stockée.
 
Bon, la traduction en PL-SQL ne doit pas poser de problème, simplement, PL-SQL préfère les curseurs aux tables tempo. Mais bon, dans ton cas, ça devrait tout de même le faire...
 
Juste un truc :
 
Les variables en Transact-SQL sont toujours préfixées par :
- @ pour les variables utilisateur (@inCompteur et @inRang ici)
- @@ pour les variables système : @@rowcount représente le nombre de lignes ramenées par la dernière requête exécutée (ici, l'insert : quand @@rowcount = 0, c'est qu'on n'a effectué aucune insertion).
 
Et les tables temporaires sont toujours préfixées par #.
 
Voilà, tu devrais pouvoir te débrouiller avec ça non?
 
Si tu n'as pas compris l'algo, demande...

 

[edit]--Message édité par Fred999--[/edit]

irulan Je pense qu'en PL/SQL sous Oracle 8 ça devrait pouvoir se faire (c'est une procédure stockée là aussi)

 

[edit]--Message édité par Irulan--[/edit]

wouatouwouatou Merci pour ton script Fred999... meme si j'y comprend pas grd chose.
Mais bon, si jai bien compris il fodrait ke je mette ca dans une procedure stockee si je veux l'utiliser, non ?
 
En fait, jai donne un script pour sqlserver paske plus rapide a ecrire... Mais en fait il me fodrait une solution pour oracle 8. :D
wouatouwouatou je viens de revoir ma problematique, (kel mot :D )
En fait, on peut resumer ca en faisant une analogie avec un ensemble de listes chainees.
Donc en fait, ma table toto serait en qq sorte un ensemble de listes chainees.
Et moi je veux une liste entiere connaissant la tete. En clair je veux une liste particuliere dans l'ensemble de liste :D.
 
Je crois ke c un peu tordu kom truc mais bon... :sarcastic:
Fred999 Tu peux faire un truc du genre :
 
create table #tmp_toto (
           a numeric(10),
           b numeric(10),
           c varchar(20),
           rang int
)
 
declare @inCompteur int
declare @inRang int
 
select @inCompteur = 1,
       @inRang = 0
 
/* Insertion initiale */
insert #tmp_toto
select
       t2.a,
       t2.b,
       t2.c,
       @inRang
from
       toto   t1,
       toto  t2
where
       t1.a = 1
and
       t1.a = t2.b
 
/* Insertions récursives */
while (@inCompteur != 0)
begin
 
   insert #tmp_toto (a, b, c, rang)
   select
          t1.a,
          t1.b,
          t1.c,
          @inRang + 1
   from
          toto  t1,
          #tmp_toto t2
   where
          t1.b = t2.a
   and
          t2.rang = @inRang
 
select @inCompteur = @@rowcount
 
select @inRang = @inRang + 1
 
end
 
select * from #tmp_toto
 
 
Bon, l'insertion initiale te donne les lignes qui sont directement reliées de premier niveau.
 
Et, ensuite, on insère les lignes reliées aux lignes du niveau donné, de manière récursive ; quand on n'en trouve plus, on sort de la boucle.
 
Le souci, c'est que si tu t'emmèles les pinceaux au momoent de l'insertion, tu risques de tourner en rond : prévoir, donc, une porte de sortie (par exemple, au niveau 50, il doit commencer à y avoir un gros souci...).
 
Bon, j'utilise une table temporaire, ça me paraît adapté à la situation, et c'est bien dans l'esprit de SQL Server (qui n'aime pas trop les curseurs...)
 
ATTENTION!!! J'avais fait une couille dans l'initialisation des variables et la condition de sortie de la boucle. C'est corrigé.

 

[edit]--Message édité par Fred999--[/edit]

Fred999 Je te donne une méthode, je pense avoir trouvé.
 
10 minutes le temps que je ponde le script.
Fred999 OK j'ai (enfin) compris. Et, effectivement, c'est un truc récursif.
wouatouwouatou Fred999> J'y avais pensé, mais de cette manière, on n'obtient que les lignes liées d'un nivo. seulement.
 
Moi il me fodrait tous les nivos: c.a.d la ligne ki est donnee par b ainsi ke celle ki est eventuellement donnee ar cette derniere, pi etc....
En fait, je pense ke le pb. est un truc recursif. Mais comment le resoudre... :??:
 
thegti> tu pourrais pas me faire le script avec les cuseur... :D paske moi jy connais kedal (enfin, pas grd chose) en curseur. :jap:
Fred999 A priori, je te proposerais ça :
 
select   t2.*
from
         toto      t1,
         toto      t2
where
         t1.a    = t2.b
and
         t1.a      = 1

 

[edit]--Message édité par Fred999--[/edit]

wouatouwouatou bah.. c pour mon histoire de jointure.
Tu sais les jointure du genre:
 
 A.1=B.1 AND B.2=C.2 AND C.3=D.2 AND etc...
 
Enfin, bref... Un chtit exemple de script plz... jsuis un peu perdu la :(
wouatouwouatou voila un script sous sql server... enfin, a ma sauce :D
 
create table toto  
(
  a numeric(10) IDENTITY PRIMARY KEY,
  b numeric(10),
  c varchar(20),
  constraint FK_toto_toto foreign key (b) references toto(a)
)
Roswell_ La solution doit être avec CONNECT BY toto un truc du genre.
Fred999 Je ne comprends pas. b référence la PK de toto, soit a?????
 
Tu peux nous mettre un pseudo-script de création de table?
thegti lut
C'est bizarre ta clé étrangère sur la même table (jamais vu un truc pareil !)
Et la récursivité n'est pas gérable sous SQL.
Transact SQL ou PL/SQL avec des boucles ca doit le faire
wouatouwouatou J'ai un table toto de trois colonnes a,b,c.
a etant la cle primaire.
b est une cle etrangere referencant toto
c est une colonne de valeurs...
 
Bon, voila le pb.: Est-il possible d'obtenir toutes les lignes dépendant d'une ligne connue.
Par exemple, je veux toutes les lignes liées a la ligne dont la colonne a vaut 1 (En supposant kil ny aura pas de recursivité sans fin avec les valeurs entre a et b)
Bien sur, la colonne b peut 'pointer' sur une ligne ki elle meme pointe sur une autre, etc...
 
Merci pour les reponses... :jap:

Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)