Précédent   Forum des professionnels en informatique > Bases de données > Sybase
Sybase Forum sur la base de données Sybase. Avant de poster -> F.A.Q Sybase, Tutoriels Sybase
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 28/06/2006, 14h58   #1
Membre du Club
 
Développeur Web
Inscription : décembre 2005
Messages : 110
Détails du profil
Informations professionnelles :
Activité : Développeur Web

Informations forums :
Inscription : décembre 2005
Messages : 110
Points : 45
Points : 45
Par défaut Problème jointure croisée et tables dérivées - Toujours pas résolu :o(

Bonjour

Avant toute chose : j'utilise ASE version 15.0.
Voilà ma requête :

Code :
1
2
3
4
5
6
7
8
9
 
SELECT table2.id_colonnes, id_types, id_vues, colonnes_nom, colonnes_champ_cible,
	colonnes_ordre, colonnes_config_type, colonnes_liste, colonnes_triable,
	colonnes_editable, colonnes_cherchable, colonnes_tag, types_nom
FROM (SELECT * FROM (SELECT sc.*, st.types_nom FROM shadow_colonnes sc INNER JOIN shadow_types st ON sc.id_types=st.id_types) table1) table2, shadow_roles sr
LEFT OUTER JOIN shadow_droits_colonnes sdc ON (table2.id_colonnes=sdc.id_colonnes AND sr.id_roles=sdc.id_roles)
WHERE table2.id_vues=87
AND sr.id_roles IN (72,73)
AND sdc.droits_collonnes_modif <> 0;
Et voilà mon erreur :

Code :
1
2
3
 
Adaptive Server cannot perform the requested action because COLUMN 'id_colonnes' IS NOT within the scope of the joined TABLE expression. CHECK your command
FOR missing OR incorrect DATABASE objects, variable names, AND/OR input DATA.
Cette erreur concerne cette ligne :

Code :
1
2
 
LEFT OUTER JOIN shadow_droits_colonnes sdc ON (table2.id_colonnes=sdc.id_colonnes AND sr.id_roles=sdc.id_roles)
Comment puis-je modifier ma requête pour que id_colonnes soit reconnue ?

Une autre question, cette requête est-elle portable ou bien est-ce une syntaxe propre à Sybase (il semblerait que Sybase ne reconnaisse pas les alias si ceux-ci sont "appelés" en dehors des parenthèses dans lesquels ils sont déclarés...)

Merci d'avance
fadeninev est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/06/2006, 16h07   #2
Membre du Club
 
Développeur Web
Inscription : décembre 2005
Messages : 110
Détails du profil
Informations professionnelles :
Activité : Développeur Web

Informations forums :
Inscription : décembre 2005
Messages : 110
Points : 45
Points : 45
J'ai trouvé cette requête qui a l'air de fonctionner :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
SELECT table3.id_colonnes, id_types, id_vues, colonnes_nom, colonnes_champ_cible,
	colonnes_ordre, colonnes_config_type, colonnes_liste, colonnes_triable,
	colonnes_editable, colonnes_cherchable, colonnes_tag, types_nom
FROM (
	SELECT * FROM (
		SELECT sc.*, st.types_nom FROM shadow_colonnes sc INNER JOIN shadow_types st ON sc.id_types=st.id_types) 
	table2, shadow_roles sr)
table3
 
LEFT OUTER JOIN shadow_droits_colonnes sdc ON (table3.id_colonnes=sdc.id_colonnes AND table3.id_roles=sdc.id_roles)
WHERE table3.id_vues=87
AND table3.id_roles IN (72,73)
AND sdc.droits_collonnes_modif <> 0;
Mais je me pose toujours la question de la portabilité de cette requête...

Merci d'avance si vous avez la réponse à ma question
fadeninev est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/06/2006, 17h23   #3
Membre du Club
 
Développeur Web
Inscription : décembre 2005
Messages : 110
Détails du profil
Informations professionnelles :
Activité : Développeur Web

Informations forums :
Inscription : décembre 2005
Messages : 110
Points : 45
Points : 45
Par défaut Nouveau souci

J'ai un nouveau souci avec cette requête, et plus particulièrement avec ce morceau là :

Code :
1
2
3
4
5
6
7
8
 
SELECT table3.id_colonnes, sdc.id_roles, sdc.droits_collonnes_voir
FROM (
	SELECT * FROM (
		SELECT sc.*, st.types_nom FROM shadow_colonnes sc INNER JOIN shadow_types st ON sc.id_types=st.id_types) 
	table2, shadow_roles sr)
table3
LEFT OUTER JOIN shadow_droits_colonnes sdc ON (table3.id_colonnes = sdc.id_colonnes AND table3.id_roles = sdc.id_roles)
Je fais une jointure croisée, et donc lorsqu'il n'y a pas de valeur commune aux 2 tables (plus précisément, mon alias "table3" et ma table "shadow_droits_colonnes"), le tuple doit quand même apparaître mais avec un 'null' à la place de la valeur qui n'est pas en commun dans les 2 tables.
Mon problème est qu'au lieu de me renvoyer null, ça me renvoit false (0) :

Code :
1
2
3
4
5
6
7
8
9
10
11
 
id_colonnes id_roles droits_collonnes_voir
 ----------- -------- ---------------------
          86       72                     1
          86       73                     1
          87       72                     0
          87     NULL                     0
          88       72                     0
          88     NULL                     0
          89     NULL                     0
          89     NULL                     0
Là où il y a null dans 'id_roles', je devrais aussi avoir null dans 'droits_collones_voir'.
Je me demande si ce n'est pas parce que le champ concerné est de type 'bit', et qu'une valeur null y est interdite.

Merci pour votre aide Ne me laissez pas sans réponse !
fadeninev est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/07/2006, 15h48   #4
Membre Expert
 
Inscription : avril 2006
Messages : 1 024
Détails du profil
Informations forums :
Inscription : avril 2006
Messages : 1 024
Points : 1 175
Points : 1 175
Par défaut attention au NULL

Attention, il faut bien avoir à l'esprit que NULL signifie "INCONNU" ou "sans objet", ce n'est pas une valeur, mais l'absence de valeur. C'est un peu comme les "ne se prononce pas" dans les sondages... Donc lorsqu'on demande à une base de donnée de comparer une colonne de valeur inconnue à une autre colonne de valeur inconnue, cette dernière ne peux pas répondre... la réponse exacte devrait être "JE SAIS PAS" ou "PTET BEN QU'OUI, PTET BEN QU'NON" mais ce genre de réponse n'étant pas prévue, elle répond systématiquement "NON".

Ca peut paraitre paradoxal mais (NULL = NULL) répond FAUX, (NULL <> NULL) répond FAUX aussi, en fait dés qu'il y a NULL dans une comparaison, la réponse est systématiquement négative sauf à la question "isnull".

C'est pour ça que toutes les lignes ayant null dans une colonne de jointure seront rejetées....
remi4444 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/07/2006, 09h21   #5
Rédacteur/Modérateur
 
Avatar de fadace
 
Homme Fabien Celaia
Administrateur de base de données
Inscription : octobre 2002
Messages : 3 779
Détails du profil
Informations personnelles :
Nom : Homme Fabien Celaia
Âge : 41
Localisation : Suisse

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : Service public

Informations forums :
Inscription : octobre 2002
Messages : 3 779
Points : 8 124
Points : 8 124
Envoyer un message via ICQ à fadace Envoyer un message via Skype™ à fadace
Citation:
Envoyé par remi4444
Attention, il faut bien avoir à l'esprit que NULL signifie "INCONNU" ou "sans objet", ce n'est pas une valeur, mais l'absence de valeur. C'est un peu comme les "ne se prononce pas" dans les sondages... Donc lorsqu'on demande à une base de donnée de comparer une colonne de valeur inconnue à une autre colonne de valeur inconnue, cette dernière ne peux pas répondre... la réponse exacte devrait être "JE SAIS PAS" ou "PTET BEN QU'OUI, PTET BEN QU'NON" mais ce genre de réponse n'étant pas prévue, elle répond systématiquement "NON".

Ca peut paraitre paradoxal mais (NULL = NULL) répond FAUX, (NULL <> NULL) répond FAUX aussi, en fait dés qu'il y a NULL dans une comparaison, la réponse est systématiquement négative sauf à la question "isnull".

C'est pour ça que toutes les lignes ayant null dans une colonne de jointure seront rejetées....
Inexact sous Sybase, bien que l'explication du NULL me plaise

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
42
43
44
45
46
47
48
1> CREATE TABLE t(i int, v varchar(30) NULL)
2> go
 
1> INSERT INTO t VALUES(1,'abc')
2> INSERT INTO t VALUES(2,NULL)
3> go
(1 row affected)
(1 row affected)
 
1> SELECT * FROM t
2> go
 i           v
 ----------- ------------------------------
           1 abc
           2 NULL
 
(2 rows affected)
 
1> SELECT * FROM t WHERE v=NULL
2> go
 i           v
 ----------- ------------------------------
           2 NULL
 
(1 row affected)
 
1> SELECT * FROM t WHERE v<>NULL
2> go
 i           v
 ----------- ------------------------------
           1 abc
 
(1 row affected)
 
1> SELECT count(*) FROM t
2> go
 
 -----------
           2
 
(1 row affected)
1> SELECT count(v) FROM t -- compte les valeurs non null
2> go
 
 -----------
           1
 
(1 row affected)
Sous Oracle et MS-SQL par contre, comportement comme spécifié

Code :
1
2
3
4
5
6
7
SQL> SELECT * FROM t WHERE v = NULL ;
 
aucune ligne sélectionnée
 
SQL> SELECT * FROM t WHERE v <> NULL ;
 
aucune ligne sélectionnée
Sous DB2, la syntaxe n'est pas acceptée

Code :
1
2
3
SELECT * FROM t WHERE v = NULL 
 
 Utilisation de NULL incorrecte.
idem sous Informix

Code :
1
2
3
SELECT * FROM t WHERE v = NULL 
 
  217: COLUMN (NULL) NOT found IN any TABLE IN the query (OR SLV IS undefined)
__________________
Sr DBA Oracle / Sybase / MS-SQL / DB2 / Informix / Postgresql
Administrateur SAP
Mes articles

Attention : pas de réponse technique par MP : pensez aux autres, passez par les forums !
fadace est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/07/2006, 11h10   #6
Membre Expert
 
Inscription : avril 2006
Messages : 1 024
Détails du profil
Informations forums :
Inscription : avril 2006
Messages : 1 024
Points : 1 175
Points : 1 175
Par défaut Certes...

Oui j'ai un peu résumé, il est vrai que sybase a cette tolérance de faire l'équivalence entre "isnull" et "=NULL" ce qui est lamentable à mon avis, puisque ça mène justement à la confusion que je dénonçait plus haut.

Mais attention, cette tolérance disparait dans les jointures!!

La preuve:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 
 
1> CREATE TABLE t(i int, v varchar(30) NULL)
2> go
 
1> INSERT INTO t VALUES(1,'abc')
2> INSERT INTO t VALUES(2,NULL)
3> go
 
1> SELECT T1.*,T2.* FROM t T1, t T2 WHERE T1.v = T2.v
2> go
 
i           v                              i           v                              
----------- -                              ----------- -                              
          1 abc                                      1 abc    
 
(1 row affected)
Etonnant non ?
remi4444 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/07/2006, 11h56   #7
Rédacteur/Modérateur
 
Inscription : janvier 2006
Messages : 1 301
Détails du profil
Informations personnelles :
Âge : 52

Informations forums :
Inscription : janvier 2006
Messages : 1 301
Points : 1 505
Points : 1 505
Envoyer un message via AIM à mpeppler
A tout ceci il faut ajouter que le comportement des valeurs NULL peut être modifié via l'option ANSI_NULL (p.ex. SET ANSI_NULL ON). Si cette option est positioné alors les égalités avec NULL ne sont pas tolérées.

Michael
__________________
Michael Peppler
Membre de TeamSybase - www.teamsybase.com

"A successful [software] tool is one that was used to do something undreamed of by its author." -- S. C. Johnson
mpeppler 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 23h59.


 
 
 
 
Partenaires

Hébergement Web