Précédent   Forum des professionnels en informatique > Bases de données > MS SQL-Server > Développement
Développement Forum d'entraide sur le Transact-SQL, le CLR, les procédures stockées, les triggers, les requêtes 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 06/01/2012, 11h59   #1
Candidat au titre de Membre du Club
 
Homme Gratien
Inscription : octobre 2009
Messages : 65
Détails du profil
Informations personnelles :
Nom : Homme Gratien

Informations forums :
Inscription : octobre 2009
Messages : 65
Points : 11
Points : 11
Par défaut Article sur Méta données

Bonjour,

Je suis en train d'étudier l'article sur les méta données pour les besoins de mon progiciel et j'ai quelques soucis.

La fin de l'article donne deux requêtes qui ne fonctionnent pas :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
SELECT *
FROM   TR_PROSPECT_PRP PRP
       LEFT OUTER JOIN T_DONNEE_DON DON
            ON PRP.PRP_ID = DON.CRE_LIGNE
       LEFT OUTER JOIN TR_TABLES_TBL TBL
            ON DON.TBL_ID = TBL.TBL_ID
       LEFT OUTER JOIN TR_CARACTERISTIQUE_CAR CAR
            ON DON.CAR_ID = CAR.CAR_ID
WHERE  TBL.TBL_SQL_NOM = 'TR_PROSPECT_PRP'
  AND  CAR.CAR_LIBELLE = 'Carac_1'
  AND  CRE.CRE_VALEUR = valeur 1
  AND  CAR.CAR_LIBELLE = 'Carac_2'
  AND  CRE.CRE_VALEUR = valeur 2
  AND  CAR.CAR_LIBELLE = 'Carac_3'
  AND  CRE.CRE_VALEUR = valeur 3
  AND  CAR.CAR_LIBELLE = 'Carac_4'
  AND  CRE.CRE_VALEUR = valeur 4
Je ne parle pas des petites coquilles dans les noms de tables et alias, mais bien de la structure de la requête.
En effet, si je comprends bien comment cela fonctionne, il ne me semble pas possible d'écrire dans la même requête :

Code :
1
2
3
4
 
  AND  DON.CRE_VALEUR = valeur 1
...
  AND  DON.CRE_VALEUR = valeur 2
Si valeur1 != valeur2 alors forcément cela ne renvoie pas de lignes.
Pour que la requête marche, il faut faire autant de jointures que de caractéristiques recherchées.

Première question : suis je dans le vrai ?

Mon deuxième problème est que je ne connais pas le nombre de caractéristiques à l'avance, je ne peux donc pas utiliser la technique des jointures multiples.

En fait je dois écrire une requête qui sélectionne des lignes dans une table. Le nombre de colonnes de cette requête est fixe. Pour chaque ligne de cette requête, je dois trouver une autre ligne dans une autre table.
Vous allez me dire que c'est tout simplement par une jointure. Oui mais, je ne connais pas le nombre ni le nom des colonnes qui servent à la jointure.

C'est pourquoi je cherche du coté des métas données. Je pense que je peux m'en sortir avec ça.

Deuxième question : suis je obligé de passer par du SQL dynamique (j'aimerais éviter) ou bien existe t-il une technique pour faire cela ?

Merci pour votre aide...
Batou69 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/01/2012, 16h57   #2
Rédacteur/Modérateur

 
Avatar de SQLpro
 
Homme Frédéric BROUARD
Expert SGBDR & SQL
Inscription : mai 2002
Messages : 10 959
Détails du profil
Informations personnelles :
Nom : Homme Frédéric BROUARD
Localisation : France

Informations professionnelles :
Activité : Expert SGBDR & SQL
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 10 959
Points : 17 791
Points : 17 791
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
SELECT *
FROM   TR_PROSPECT_PRP PRP
       LEFT OUTER JOIN T_DONNEE_DON DON
            ON PRP.PRP_ID = DON.CRE_LIGNE
       LEFT OUTER JOIN TR_TABLES_TBL TBL
            ON DON.TBL_ID = TBL.TBL_ID
       LEFT OUTER JOIN TR_CARACTERISTIQUE_CAR C1
            ON DON.CAR_ID = C1.CAR_ID
       LEFT OUTER JOIN TR_CARACTERISTIQUE_CAR C2
            ON DON.CAR_ID = C2.CAR_ID
       LEFT OUTER JOIN TR_CARACTERISTIQUE_CAR C3
            ON DON.CAR_ID = C3.CAR_ID
       LEFT OUTER JOIN TR_CARACTERISTIQUE_CAR C4
            ON DON.CAR_ID = C4.CAR_ID
WHERE  TBL.TBL_SQL_NOM = 'TR_PROSPECT_PRP'
  AND  C1.CAR_LIBELLE = 'Carac_1'
  AND  C1.CRE_VALEUR = valeur 1
  AND  C2.CAR_LIBELLE = 'Carac_2'
  AND  C2.CRE_VALEUR = valeur 2
  AND  C3.CAR_LIBELLE = 'Carac_3'
  AND  C3.CRE_VALEUR = valeur 3
  AND  C4.CAR_LIBELLE = 'Carac_4'
  AND  C4.CRE_VALEUR = valeur 4
Sinon, faisable avec du SQL récursif auquel vous passez dans un ou deux clauses IN les données caractéristiques et valeurs.
A lire sur les requêtes récursives : http://sqlpro.developpez.com/cours/s...te-recursives/

A +
__________________
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro
http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation
* * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *
SQLpro est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/01/2012, 10h19   #3
Candidat au titre de Membre du Club
 
Homme Gratien
Inscription : octobre 2009
Messages : 65
Détails du profil
Informations personnelles :
Nom : Homme Gratien

Informations forums :
Inscription : octobre 2009
Messages : 65
Points : 11
Points : 11
Citation:
Envoyé par SQLpro Voir le message
Arf j'aurais plutot fait :

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
 
SELECT *
FROM   TR_PROSPECT_PRP PRP
       INNER JOIN TR_TABLES_TBL TBL
            ON TBL.TBL_SQL_NOM = 'TR_PROSPECT_PRP'
       LEFT OUTER JOIN TR_DONNEES_DON DON1
            ON PRP.PRP_ID = DON1.CRE_LIGNE
       LEFT OUTER JOIN TR_DONNEES_DON DON2
            ON PRP.PRP_ID = DON2.CRE_LIGNE
       LEFT OUTER JOIN TR_DONNEES_DON DON3
            ON PRP.PRP_ID = DON3.CRE_LIGNE
       LEFT OUTER JOIN TR_DONNEES_DON DON4
            ON PRP.PRP_ID = DON4.CRE_LIGNE
       LEFT OUTER JOIN TR_CARACTERISTIQUE_CAR C1
            ON DON1.CAR_ID = C1.CAR_ID
       LEFT OUTER JOIN TR_CARACTERISTIQUE_CAR C2
            ON DON2.CAR_ID = C2.CAR_ID
       LEFT OUTER JOIN TR_CARACTERISTIQUE_CAR C3
            ON DON3.CAR_ID = C3.CAR_ID
       LEFT OUTER JOIN TR_CARACTERISTIQUE_CAR C4
            ON DON4.CAR_ID = C4.CAR_ID
WHERE  C1.CAR_LIBELLE = 'Carac_1'
  AND  DON1.TBL_ID = TBL.TBL_ID
  AND  DON1.CRE_VALEUR = ''
  AND  C2.CAR_LIBELLE = 'Carac_2'
  AND  DON2.TBL_ID = TBL.TBL_ID
  AND  DON2.CRE_VALEUR = ''
  AND  C3.CAR_LIBELLE = 'Carac_3'
  AND  DON3.TBL_ID = TBL.TBL_ID
  AND  DON3.CRE_VALEUR = ''
  AND  C4.CAR_LIBELLE = 'Carac_4'
  AND  DON4.TBL_ID = TBL.TBL_ID
  AND  DON4.CRE_VALEUR = ''
Mais j'ai plus l'habitude d'écrire les condition au plus proche des tables concernées:

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
SELECT *
FROM   TR_PROSPECT_PRP PRP
       INNER JOIN TR_TABLES_TBL TBL
            ON TBL.TBL_SQL_NOM = 'TR_PROSPECT_PRP'
       LEFT OUTER JOIN TR_DONNEES_DON DON1
            ON PRP.PRP_ID = DON1.CRE_LIGNE
  AND  DON1.TBL_ID = TBL.TBL_ID
  AND  DON1.CRE_VALEUR = ''
      LEFT OUTER JOIN TR_DONNEES_DON DON2
            ON PRP.PRP_ID = DON2.CRE_LIGNE
  AND  DON2.TBL_ID = TBL.TBL_ID
  AND  DON2.CRE_VALEUR = ''
       LEFT OUTER JOIN TR_DONNEES_DON DON3
            ON PRP.PRP_ID = DON3.CRE_LIGNE
  AND  DON3.TBL_ID = TBL.TBL_ID
  AND  DON3.CRE_VALEUR = ''
       LEFT OUTER JOIN TR_DONNEES_DON DON4
            ON PRP.PRP_ID = DON4.CRE_LIGNE
  AND  DON4.TBL_ID = TBL.TBL_ID
  AND  DON4.CRE_VALEUR = ''
       LEFT OUTER JOIN TR_CARACTERISTIQUE_CAR C1
            ON DON1.CAR_ID = C1.CAR_ID
  AND  C1.CAR_LIBELLE = 'Carac_1'
       LEFT OUTER JOIN TR_CARACTERISTIQUE_CAR C2
            ON DON2.CAR_ID = C2.CAR_ID
  AND  C2.CAR_LIBELLE = 'Carac_2'
       LEFT OUTER JOIN TR_CARACTERISTIQUE_CAR C3
            ON DON3.CAR_ID = C3.CAR_ID
  AND  C3.CAR_LIBELLE = 'Carac_3'
       LEFT OUTER JOIN TR_CARACTERISTIQUE_CAR C4
            ON DON4.CAR_ID = C4.CAR_ID
  AND  C4.CAR_LIBELLE = 'Carac_4'
Et là j'ai une grosse différence avec la première : celle ci fait des scans d'index tandis que la première fait des seek, ce qui est nettement mieux.
Je suis sous 2008 R2 Dev edition. Peut être parceque je n'ai pas de données dans les tables ( ou juste une ligne ou deux ) ??

Qu'en pensez vous ? La deuxième syntaxe est elle correcte et efficace ?

Merci !
Batou69 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/01/2012, 10h28   #4
Candidat au titre de Membre du Club
 
Homme Gratien
Inscription : octobre 2009
Messages : 65
Détails du profil
Informations personnelles :
Nom : Homme Gratien

Informations forums :
Inscription : octobre 2009
Messages : 65
Points : 11
Points : 11
Citation:
Envoyé par SQLpro Voir le message
Sinon, faisable avec du SQL récursif auquel vous passez dans un ou deux clauses IN les données caractéristiques et valeurs.
A lire sur les requêtes récursives : http://sqlpro.developpez.com/cours/s...te-recursives/

A +
Merci, il se trouve que je connais par coeur cet article qui m'a sauvé pour le calcul d'optimisation de chemin dans un graphe orienté.

Mais en fait je n'ai pas l'impression que cela peut s'adapter à mon cas. Si je vous suis bien, vous imaginez que j'ai une saisie utilisateur. Ce n'est pas le cas.

Ma structure de base est en cours de conception. Je cherche, avant de décrire mes tables, à dégrossir la requête pour faire la structure la plus adaptée à mon problème. Je ne sais pas si ma méthodologie est la meilleure, mais en général, c'est pour moi plus facile.

Donc j'ai deux tables T1 et T2 avec leurs colonnes une clef sur un entier. T1 et T2 n'ont rien à voir l'une avec l'autre. Je souhaite réaliser une jointure entre T1 et T2 sur des colonnes de T1. La difficulté c'est que le nombre, la nature et le nom des colonnes doit être paramétrable.

J'ai compris que la requête qui permettra de lire T2 à partir de T1 sera dynamique et du style de celle que j'ai posté dans mon message précédent. Je me demande par contre comment représenter ce paramétrage dans la base. Y a t il des exemple de cela quelque part ???

PS : cerise sur le gâteau la requête devra aussi être triée selon des critères paramétrables....

PS2 : si cela est plus parlant, je peut proposer des scripts bateaux pour décrire mon souci


Merci !
Batou69 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 04h17.


 
 
 
 
Partenaires

Hébergement Web