Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Base de données ou flou artistique?

29 réponses
Avatar
LiR
Bonjour à tous,

Je crée une requête Sélection dans Access XP SP3.
Cette requête repose sur une requête et 3 tables, liées par des jointures,
mais peu importe en fait.

1.
Je mets une condition sur un champ d'une des tables
La requête me renvoie alors zéro enregistrement

2.
J'ajoute une seconde condition sur un autre champ d'une autre table de la
requête
Cette condition est ajoutée sur la même ligne q'en 1., donc elle est liée
par AND à la première condition
La requête me renvoie plusieurs enregistrements

Ce comportement est, vous en conviendrez, tout simplement impossible
théoriquement.

Pour l'info (mais cela n'a aucun effet sur le principe) :
Condition 1 sur le champ 1 : Vrai Ou Est Null
Condition 2 sur le champ 1 : <>0

A noter, pour s'étonner encore un peu, que si je mets comme condition 2 : >0
Alors la requête, à nouveau, me retourne zéro enregistrement

Quelqu'un saurait d'où peut venir un comportement aussi catastrophique?

10 réponses

1 2 3
Avatar
Thierry
Bonjour,
Vous écrivez :
"...liés par des jointures, mais peu importe en fait."

Je ne suis pas un grand spécialiste en Access, mais s'il y a bien une chose
que
j'ai compris c'est que tout se joue dans les relations et les types de
jointure
dans les tables et les requêtes.
A mon avis, vous devriez creuser de ce côté là...
Bon courage.


"LiR" a écrit :

Bonjour tous,

Je cre une requte Slection dans Access XP SP3.
Cette requte repose sur une requte et 3 tables, lies par des jointures,
mais peu importe en fait.

1.
Je mets une condition sur un champ d'une des tables
La requte me renvoie alors zro enregistrement

2.
J'ajoute une seconde condition sur un autre champ d'une autre table de la
requte
Cette condition est ajoute sur la mme ligne q'en 1., donc elle est lie
par AND la premire condition
La requte me renvoie plusieurs enregistrements

Ce comportement est, vous en conviendrez, tout simplement impossible
thoriquement.

Pour l'info (mais cela n'a aucun effet sur le principe) :
Condition 1 sur le champ 1 : Vrai Ou Est Null
Condition 2 sur le champ 1 : <>0

A noter, pour s'tonner encore un peu, que si je mets comme condition 2 : >0
Alors la requte, nouveau, me retourne zro enregistrement

Quelqu'un saurait d'o peut venir un comportement aussi catastrophique?



Avatar
LiR
Bonjour,

Merci pour votre réponse.

Comme je disais, il ne s'agit pas d'un problème de relations ni de tables.

Le fait est simple :
Si une condition 1 n'est pas vérifiée
Alors le fait d'ajouter une condition 2 sous la forme (Condition 1 AND
Condition 2) donne une condition résultante (appelons-la Condition 3) qui n'a
aucune chance d'être vérifiée.

Microsoft Access a ce pouvoir inquiétant de trouver des résultats à la
Condition 3 mais pas à la Condition 1.
Ce qui, mathématiquement, est impossible.
Il s'agit ici, clairement, d'un comportement anormal.

Seulement j'aimerais pouvoir faire fonctionner Access normalement car j'ai
besoin d'un base de données qui fonctionne...


"Thierry" a écrit :

Bonjour,
Vous écrivez :
"...liés par des jointures, mais peu importe en fait."

Je ne suis pas un grand spécialiste en Access, mais s'il y a bien une chose
que
j'ai compris c'est que tout se joue dans les relations et les types de
jointure
dans les tables et les requêtes.
A mon avis, vous devriez creuser de ce côté là...
Bon courage.


"LiR" a écrit :

> Bonjour tous,
>
> Je cre une requte Slection dans Access XP SP3.
> Cette requte repose sur une requte et 3 tables, lies par des jointures,
> mais peu importe en fait.
>
> 1.
> Je mets une condition sur un champ d'une des tables
> La requte me renvoie alors zro enregistrement
>
> 2.
> J'ajoute une seconde condition sur un autre champ d'une autre table de la
> requte
> Cette condition est ajoute sur la mme ligne q'en 1., donc elle est lie
> par AND la premire condition
> La requte me renvoie plusieurs enregistrements
>
> Ce comportement est, vous en conviendrez, tout simplement impossible
> thoriquement.
>
> Pour l'info (mais cela n'a aucun effet sur le principe) :
> Condition 1 sur le champ 1 : Vrai Ou Est Null
> Condition 2 sur le champ 1 : <>0
>
> A noter, pour s'tonner encore un peu, que si je mets comme condition 2 : >0
> Alors la requte, nouveau, me retourne zro enregistrement
>
> Quelqu'un saurait d'o peut venir un comportement aussi catastrophique?
>


Avatar
Sylvain Lafontaine
Peut-être que si vous nous montreriez votre requête SQL - avec si possible
le détail pertinent des tables et des données - on pourrait tous ensemble
regarder cela et trouver où se trouve votre erreur et réduire votre
étonnement à un niveau plus acceptable.

--
Sylvain Lafontaine, ing.
MVP pour « Windows Live Platform »
Courriel: sylvain aei ca (remplissez les blancs, svp.)
Consultant indépendant et programmation à distance pour Access et
SQL-Server.


"LiR" wrote in message
news:
Bonjour à tous,

Je crée une requête Sélection dans Access XP SP3.
Cette requête repose sur une requête et 3 tables, liées par des jointures,
mais peu importe en fait.

1.
Je mets une condition sur un champ d'une des tables
La requête me renvoie alors zéro enregistrement

2.
J'ajoute une seconde condition sur un autre champ d'une autre table de la
requête
Cette condition est ajoutée sur la même ligne q'en 1., donc elle est liée
par AND à la première condition
La requête me renvoie plusieurs enregistrements

Ce comportement est, vous en conviendrez, tout simplement impossible
théoriquement.

Pour l'info (mais cela n'a aucun effet sur le principe) :
Condition 1 sur le champ 1 : Vrai Ou Est Null
Condition 2 sur le champ 1 : <>0

A noter, pour s'étonner encore un peu, que si je mets comme condition 2 :
>0
Alors la requête, à nouveau, me retourne zéro enregistrement

Quelqu'un saurait d'où peut venir un comportement aussi catastrophique?


Avatar
LiR
Bonjour,

Voici le contenu exhaustif des objets de ma base (3 tables et 2 requêtes)

TABLE : apDevisStatus
-------------------------
N_DEVISSTATUS : Entier long (PRIMARY_KEY)
devisstatus_label : Texte(32)
devisstatus_ok : Oui/Non

TABLE : DossierEtbObj
-------------------------
ID_DOSSETBOBJ : NuméroAuto (PRIMARY_KEY)
dossetbobj_etat : Entier long

TABLE : InstrDevis
--------------------
ID_INSTRDEVIS : Entier long (PRIMARY_KEY)
IDR_DOSSETBOBJ : Entier long
devs_date : Date/Heure

REQUÊTE : test_0003
------------------------
SELECT InstrDevis.ID_INSTRDEVIS
FROM (apDevisStatus RIGHT JOIN DossierEtbObj ON apDevisStatus.N_DEVISSTATUS
= DossierEtbObj.dossetbobj_etat) INNER JOIN InstrDevis ON
DossierEtbObj.ID_DOSSETBOBJ = InstrDevis.IDR_DOSSETBOBJ
WHERE (((apDevisStatus.devisstatus_ok)=True Or
(apDevisStatus.devisstatus_ok) Is Null));

REQUÊTE : test_0004
------------------------
SELECT InstrDevis.ID_INSTRDEVIS
FROM (apDevisStatus RIGHT JOIN DossierEtbObj ON apDevisStatus.N_DEVISSTATUS
= DossierEtbObj.dossetbobj_etat) INNER JOIN InstrDevis ON
DossierEtbObj.ID_DOSSETBOBJ = InstrDevis.IDR_DOSSETBOBJ
WHERE (((apDevisStatus.devisstatus_ok)=True Or
(apDevisStatus.devisstatus_ok) Is Null) AND ((InstrDevis.ID_INSTRDEVIS) Is
Not Null));


Il n'y a absolument rien d'autre dans ma base en dehors de ces 3 tables et
ces 2 requêtes
Ni autre table (sauf les tables système, évidemment), ni autre requête, ni
formulaire, ni état, bi module VBA, ni page de données, ni macro... rien.

La requête test_003 ne retourne aucun enregistrement
La requête test_003 ne retourne plusieurs enregistrements

Comme vous pouvez le voir, la seule différence entre les 2 requêtes est que
test_004 a une condition de plus dans la clause WHERE
Cette condition est : AND ((InstrDevis.ID_INSTRDEVIS) Is Not Null))

Le fait est que, mathématiquement, il est impossible que la requête test_004
retourne plus de résultats que test_003
Pour la simple et bonne raison que mathématiquement (A AND B AND C) peut
être VRAI uniquement si (A AND B) est VRAI!

Si vous reproduisez ma base à partir du modèle ci-dessus, elle fonctionnera,
fort heureusement correctement.
Le problème constaté concerne ma base, qui semble être endommagée...

Seulement j'ai vérifié les index, clés primaires, contraintes....
J'ai compacté, importé, recompacté...
Rien à faire.
Je n'arrive pas à mettre la main sur le petit grain de sel qui fait
dérailler ma base.
A moins que ce soit un immense rocher (comme toujours, plus c'est gros...)


"Sylvain Lafontaine" a écrit dans le
message de news:
Peut-être que si vous nous montreriez votre requête SQL - avec si possible
le détail pertinent des tables et des données - on pourrait tous ensemble
regarder cela et trouver où se trouve votre erreur et réduire votre
étonnement à un niveau plus acceptable.

--
Sylvain Lafontaine, ing.
MVP pour « Windows Live Platform »
Courriel: sylvain aei ca (remplissez les blancs, svp.)
Consultant indépendant et programmation à distance pour Access et
SQL-Server.


"LiR" wrote in message
news:
Bonjour à tous,

Je crée une requête Sélection dans Access XP SP3.
Cette requête repose sur une requête et 3 tables, liées par des
jointures, mais peu importe en fait.

1.
Je mets une condition sur un champ d'une des tables
La requête me renvoie alors zéro enregistrement

2.
J'ajoute une seconde condition sur un autre champ d'une autre table de la
requête
Cette condition est ajoutée sur la même ligne q'en 1., donc elle est liée
par AND à la première condition
La requête me renvoie plusieurs enregistrements

Ce comportement est, vous en conviendrez, tout simplement impossible
théoriquement.

Pour l'info (mais cela n'a aucun effet sur le principe) :
Condition 1 sur le champ 1 : Vrai Ou Est Null
Condition 2 sur le champ 1 : <>0

A noter, pour s'étonner encore un peu, que si je mets comme condition 2 :
>0
Alors la requête, à nouveau, me retourne zéro enregistrement

Quelqu'un saurait d'où peut venir un comportement aussi catastrophique?






Avatar
Michel__D
Bonjour,

"LiR" a écrit dans le message de news:
Bonjour,

Merci pour votre réponse.

Comme je disais, il ne s'agit pas d'un problème de relations ni de tables.

Le fait est simple :
Si une condition 1 n'est pas vérifiée
Alors le fait d'ajouter une condition 2 sous la forme (Condition 1 AND
Condition 2) donne une condition résultante (appelons-la Condition 3) qui n'a
aucune chance d'être vérifiée.

Microsoft Access a ce pouvoir inquiétant de trouver des résultats à la
Condition 3 mais pas à la Condition 1.
Ce qui, mathématiquement, est impossible.
Il s'agit ici, clairement, d'un comportement anormal.



Pour que l'on puisse en juger, il faut fournir des infos plus précises, à moins
que tu veuille rester dans l'incertitude.
Avatar
Sylvain Lafontaine
Premièrement, vous devriez aussi nous donner quelques exemples de lignes de
data afin que tout le monde puisse reproduire à l'identique votre problème
(le nombre minimum de lignes requises si possible et si vous êtes capable de
le faire, sous le format de requête INSERT).

Deuxièmement, comme vous utilisez des RIGHT JOIN sous Access, il faut
peut-être pas trop chercher à comprendre. Probablement que sur SQL-Server,
vous obtiendrez le résultat désiré.

Aussi, les RIGHT JOIN sont plus difficiles à lire et à interpréter que les
LEFT JOIN; vous devriez arrêter d'utiliser des RIGHT JOIN et utiliser
exclusivement des LEFT JOIN. Il est également possible qu'un utilisant un
Left Join à la place d'un Right Join qu'Access va vous donner le résultat
voulu. Avec JET, on ne sait jamais.

--
Sylvain Lafontaine, ing.
MVP pour « Windows Live Platform »
Courriel: sylvain aei ca (remplissez les blancs, svp.)
Consultant indépendant et programmation à distance pour Access et
SQL-Server.


"LiR" wrote in message
news:
Bonjour,

Voici le contenu exhaustif des objets de ma base (3 tables et 2 requêtes)

TABLE : apDevisStatus
-------------------------
N_DEVISSTATUS : Entier long (PRIMARY_KEY)
devisstatus_label : Texte(32)
devisstatus_ok : Oui/Non

TABLE : DossierEtbObj
-------------------------
ID_DOSSETBOBJ : NuméroAuto (PRIMARY_KEY)
dossetbobj_etat : Entier long

TABLE : InstrDevis
--------------------
ID_INSTRDEVIS : Entier long (PRIMARY_KEY)
IDR_DOSSETBOBJ : Entier long
devs_date : Date/Heure

REQUÊTE : test_0003
------------------------
SELECT InstrDevis.ID_INSTRDEVIS
FROM (apDevisStatus RIGHT JOIN DossierEtbObj ON
apDevisStatus.N_DEVISSTATUS = DossierEtbObj.dossetbobj_etat) INNER JOIN
InstrDevis ON DossierEtbObj.ID_DOSSETBOBJ = InstrDevis.IDR_DOSSETBOBJ
WHERE (((apDevisStatus.devisstatus_ok)=True Or
(apDevisStatus.devisstatus_ok) Is Null));

REQUÊTE : test_0004
------------------------
SELECT InstrDevis.ID_INSTRDEVIS
FROM (apDevisStatus RIGHT JOIN DossierEtbObj ON
apDevisStatus.N_DEVISSTATUS = DossierEtbObj.dossetbobj_etat) INNER JOIN
InstrDevis ON DossierEtbObj.ID_DOSSETBOBJ = InstrDevis.IDR_DOSSETBOBJ
WHERE (((apDevisStatus.devisstatus_ok)=True Or
(apDevisStatus.devisstatus_ok) Is Null) AND ((InstrDevis.ID_INSTRDEVIS) Is
Not Null));


Il n'y a absolument rien d'autre dans ma base en dehors de ces 3 tables et
ces 2 requêtes
Ni autre table (sauf les tables système, évidemment), ni autre requête, ni
formulaire, ni état, bi module VBA, ni page de données, ni macro... rien.

La requête test_003 ne retourne aucun enregistrement
La requête test_003 ne retourne plusieurs enregistrements

Comme vous pouvez le voir, la seule différence entre les 2 requêtes est
que test_004 a une condition de plus dans la clause WHERE
Cette condition est : AND ((InstrDevis.ID_INSTRDEVIS) Is Not Null))

Le fait est que, mathématiquement, il est impossible que la requête
test_004 retourne plus de résultats que test_003
Pour la simple et bonne raison que mathématiquement (A AND B AND C) peut
être VRAI uniquement si (A AND B) est VRAI!

Si vous reproduisez ma base à partir du modèle ci-dessus, elle
fonctionnera, fort heureusement correctement.
Le problème constaté concerne ma base, qui semble être endommagée...

Seulement j'ai vérifié les index, clés primaires, contraintes....
J'ai compacté, importé, recompacté...
Rien à faire.
Je n'arrive pas à mettre la main sur le petit grain de sel qui fait
dérailler ma base.
A moins que ce soit un immense rocher (comme toujours, plus c'est gros...)


"Sylvain Lafontaine" a écrit dans le
message de news:
Peut-être que si vous nous montreriez votre requête SQL - avec si
possible le détail pertinent des tables et des données - on pourrait tous
ensemble regarder cela et trouver où se trouve votre erreur et réduire
votre étonnement à un niveau plus acceptable.

--
Sylvain Lafontaine, ing.
MVP pour « Windows Live Platform »
Courriel: sylvain aei ca (remplissez les blancs, svp.)
Consultant indépendant et programmation à distance pour Access et
SQL-Server.


"LiR" wrote in message
news:
Bonjour à tous,

Je crée une requête Sélection dans Access XP SP3.
Cette requête repose sur une requête et 3 tables, liées par des
jointures, mais peu importe en fait.

1.
Je mets une condition sur un champ d'une des tables
La requête me renvoie alors zéro enregistrement

2.
J'ajoute une seconde condition sur un autre champ d'une autre table de
la requête
Cette condition est ajoutée sur la même ligne q'en 1., donc elle est
liée par AND à la première condition
La requête me renvoie plusieurs enregistrements

Ce comportement est, vous en conviendrez, tout simplement impossible
théoriquement.

Pour l'info (mais cela n'a aucun effet sur le principe) :
Condition 1 sur le champ 1 : Vrai Ou Est Null
Condition 2 sur le champ 1 : <>0

A noter, pour s'étonner encore un peu, que si je mets comme condition 2
: >0
Alors la requête, à nouveau, me retourne zéro enregistrement

Quelqu'un saurait d'où peut venir un comportement aussi catastrophique?









Avatar
LiR
Bonjour,

Voici les données


TABLE : apDevisStatus
-------------------------
C'est simple : aucun enregistrement


TABLE : DossierEtbObj
-------------------------

10000 enregistrements, avec :
ID_DOSSETBOBJ : de 1 à 10000
dossetbobj_etat : NULL partout

TABLE : InstrDevis
--------------------

10000 enregistrements, avec :
ID_INSTRDEVIS : de 1 à 10000
IDR_DOSSETBOBJ : égal à ID_INSTRDEVIS


Avec ces valeurs, la requête test_003 ne retourne aucun enregistrement

Ce qui est très intéressant, c'est que si je supprime les enregistrements
des tables DossierEtbObj et InstrDevis au dessus de 1000,
c'est-à-dire que je garde 1000 enregistrements dans chaque table,
avec les ID allant de 1 à 1000, alors là, Ô miracle :
La requête test_003 renvoie.... tenez vous bien.... 1000 enregistrements
avec ID_INSTRDEVIS allant de 1 à 1000.
On n'en attendait pas moins d'elle, elle a été concue pour cela!

Alors elle peut retourner 1000 enregistrements, mais 10000 semble être trop
lui demander.
J'espère que vous comprenez bien désormais l'étendue du problème.


Alors juste pour finir, la cerise sur le gâteau :

La requête check_003 suivante :

SELECT InstrDevis.ID_INSTRDEVIS, apDevisStatus.N_DEVISSTATUS,
apDevisStatus.devisstatus_ok
FROM (apDevisStatus RIGHT JOIN DossierEtbObj ON apDevisStatus.N_DEVISSTATUS
= DossierEtbObj.dossetbobj_etat) INNER JOIN InstrDevis ON
DossierEtbObj.ID_DOSSETBOBJ = InstrDevis.IDR_DOSSETBOBJ

Cette requête est exactement la même que test_003
mais elle ne filtre pas et elle affiche les champs pour vérification
Cette requête check_003 renvoie 10000 enregistrement avec N_DEVISSTATUS à
NULL partout (normal, puisqu'il n'y a AUCUN enregistrement dans la table
apDevisStatus), mais devisstatus_ok à 0 (zéro) partout.

Alors d'où sort ce zéro dans le champ devisstatus_ok ???

Note : pour observer le résultat de la requête check_003,
dans les propriétés du champ devisstatus_ok
j'ai enlevé le format "oui/non" et l'affichage du contrôle "case à cocher"

Donc :
Sous certaines conditions, MS Jet peut comprendre qu'un booléen absent vaut
NULL.
Sous d'autres, il ne peut pas estimer qu'un Booléen puisse valoir autre
chose que 0 ou -1.

Inutile de dire qu'une solution serait de changer le type de données du
champ devisstatus_ok en numérique entier (dans ce cas, effectivement,
test_0003 renvoie les enregistrement, même s'il y en a 10000).

Je vous remercie de votre attention,

LiR

"Sylvain Lafontaine" a écrit :

Premièrement, vous devriez aussi nous donner quelques exemples de lignes de
data afin que tout le monde puisse reproduire à l'identique votre problème
(le nombre minimum de lignes requises si possible et si vous êtes capable de
le faire, sous le format de requête INSERT).

Deuxièmement, comme vous utilisez des RIGHT JOIN sous Access, il faut
peut-être pas trop chercher à comprendre. Probablement que sur SQL-Server,
vous obtiendrez le résultat désiré.

Aussi, les RIGHT JOIN sont plus difficiles à lire et à interpréter que les
LEFT JOIN; vous devriez arrêter d'utiliser des RIGHT JOIN et utiliser
exclusivement des LEFT JOIN. Il est également possible qu'un utilisant un
Left Join à la place d'un Right Join qu'Access va vous donner le résultat
voulu. Avec JET, on ne sait jamais.

--
Sylvain Lafontaine, ing.
MVP pour « Windows Live Platform »
Courriel: sylvain aei ca (remplissez les blancs, svp.)
Consultant indépendant et programmation à distance pour Access et
SQL-Server.


"LiR" wrote in message
news:
> Bonjour,
>
> Voici le contenu exhaustif des objets de ma base (3 tables et 2 requêtes)
>
> TABLE : apDevisStatus
> -------------------------
> N_DEVISSTATUS : Entier long (PRIMARY_KEY)
> devisstatus_label : Texte(32)
> devisstatus_ok : Oui/Non
>
> TABLE : DossierEtbObj
> -------------------------
> ID_DOSSETBOBJ : NuméroAuto (PRIMARY_KEY)
> dossetbobj_etat : Entier long
>
> TABLE : InstrDevis
> --------------------
> ID_INSTRDEVIS : Entier long (PRIMARY_KEY)
> IDR_DOSSETBOBJ : Entier long
> devs_date : Date/Heure
>
> REQUÊTE : test_0003
> ------------------------
> SELECT InstrDevis.ID_INSTRDEVIS
> FROM (apDevisStatus RIGHT JOIN DossierEtbObj ON
> apDevisStatus.N_DEVISSTATUS = DossierEtbObj.dossetbobj_etat) INNER JOIN
> InstrDevis ON DossierEtbObj.ID_DOSSETBOBJ = InstrDevis.IDR_DOSSETBOBJ
> WHERE (((apDevisStatus.devisstatus_ok)=True Or
> (apDevisStatus.devisstatus_ok) Is Null));
>
> REQUÊTE : test_0004
> ------------------------
> SELECT InstrDevis.ID_INSTRDEVIS
> FROM (apDevisStatus RIGHT JOIN DossierEtbObj ON
> apDevisStatus.N_DEVISSTATUS = DossierEtbObj.dossetbobj_etat) INNER JOIN
> InstrDevis ON DossierEtbObj.ID_DOSSETBOBJ = InstrDevis.IDR_DOSSETBOBJ
> WHERE (((apDevisStatus.devisstatus_ok)=True Or
> (apDevisStatus.devisstatus_ok) Is Null) AND ((InstrDevis.ID_INSTRDEVIS) Is
> Not Null));
>
>
> Il n'y a absolument rien d'autre dans ma base en dehors de ces 3 tables et
> ces 2 requêtes
> Ni autre table (sauf les tables système, évidemment), ni autre requête, ni
> formulaire, ni état, bi module VBA, ni page de données, ni macro... rien.
>
> La requête test_003 ne retourne aucun enregistrement
> La requête test_003 ne retourne plusieurs enregistrements
>
> Comme vous pouvez le voir, la seule différence entre les 2 requêtes est
> que test_004 a une condition de plus dans la clause WHERE
> Cette condition est : AND ((InstrDevis.ID_INSTRDEVIS) Is Not Null))
>
> Le fait est que, mathématiquement, il est impossible que la requête
> test_004 retourne plus de résultats que test_003
> Pour la simple et bonne raison que mathématiquement (A AND B AND C) peut
> être VRAI uniquement si (A AND B) est VRAI!
>
> Si vous reproduisez ma base à partir du modèle ci-dessus, elle
> fonctionnera, fort heureusement correctement.
> Le problème constaté concerne ma base, qui semble être endommagée...
>
> Seulement j'ai vérifié les index, clés primaires, contraintes....
> J'ai compacté, importé, recompacté...
> Rien à faire.
> Je n'arrive pas à mettre la main sur le petit grain de sel qui fait
> dérailler ma base.
> A moins que ce soit un immense rocher (comme toujours, plus c'est gros...)
>
>
> "Sylvain Lafontaine" a écrit dans le
> message de news:
>> Peut-être que si vous nous montreriez votre requête SQL - avec si
>> possible le détail pertinent des tables et des données - on pourrait tous
>> ensemble regarder cela et trouver où se trouve votre erreur et réduire
>> votre étonnement à un niveau plus acceptable.
>>
>> --
>> Sylvain Lafontaine, ing.
>> MVP pour « Windows Live Platform »
>> Courriel: sylvain aei ca (remplissez les blancs, svp.)
>> Consultant indépendant et programmation à distance pour Access et
>> SQL-Server.
>>
>>
>> "LiR" wrote in message
>> news:
>>> Bonjour à tous,
>>>
>>> Je crée une requête Sélection dans Access XP SP3.
>>> Cette requête repose sur une requête et 3 tables, liées par des
>>> jointures, mais peu importe en fait.
>>>
>>> 1.
>>> Je mets une condition sur un champ d'une des tables
>>> La requête me renvoie alors zéro enregistrement
>>>
>>> 2.
>>> J'ajoute une seconde condition sur un autre champ d'une autre table de
>>> la requête
>>> Cette condition est ajoutée sur la même ligne q'en 1., donc elle est
>>> liée par AND à la première condition
>>> La requête me renvoie plusieurs enregistrements
>>>
>>> Ce comportement est, vous en conviendrez, tout simplement impossible
>>> théoriquement.
>>>
>>> Pour l'info (mais cela n'a aucun effet sur le principe) :
>>> Condition 1 sur le champ 1 : Vrai Ou Est Null
>>> Condition 2 sur le champ 1 : <>0
>>>
>>> A noter, pour s'étonner encore un peu, que si je mets comme condition 2
>>> : >0
>>> Alors la requête, à nouveau, me retourne zéro enregistrement
>>>
>>> Quelqu'un saurait d'où peut venir un comportement aussi catastrophique?
>>
>>
>





Avatar
Dragan
Bonjour LiR,
il n'y a aucun problème. Les valeurs TRUE et FALSE sont en fait des
constantes de programmation pour un entier long, sous VBA access TRUE = -1 et
FALSE = 0; ces constantes n'existent pas sous SQL. Il faut donc dans une
requête les remplacer par leur valeur.
En clair, il faut juste remplacer :
devisstatus_ok=true :
devisstatus_ok=-1 ou (devistatus_ok<>0 AND NOT devisstatus_ok IS NULL)
devisstatus_okúlse :
devistatus_ok=0 ou (devistatus_ok<>-1 AND NOT devisstatus_ok IS NULL)



"LiR" a écrit :

Bonjour,

Voici les données


TABLE : apDevisStatus
-------------------------
C'est simple : aucun enregistrement


TABLE : DossierEtbObj
-------------------------

10000 enregistrements, avec :
ID_DOSSETBOBJ : de 1 à 10000
dossetbobj_etat : NULL partout

TABLE : InstrDevis
--------------------

10000 enregistrements, avec :
ID_INSTRDEVIS : de 1 à 10000
IDR_DOSSETBOBJ : égal à ID_INSTRDEVIS


Avec ces valeurs, la requête test_003 ne retourne aucun enregistrement

Ce qui est très intéressant, c'est que si je supprime les enregistrements
des tables DossierEtbObj et InstrDevis au dessus de 1000,
c'est-à-dire que je garde 1000 enregistrements dans chaque table,
avec les ID allant de 1 à 1000, alors là, Ô miracle :
La requête test_003 renvoie.... tenez vous bien.... 1000 enregistrements
avec ID_INSTRDEVIS allant de 1 à 1000.
On n'en attendait pas moins d'elle, elle a été concue pour cela!

Alors elle peut retourner 1000 enregistrements, mais 10000 semble être trop
lui demander.
J'espère que vous comprenez bien désormais l'étendue du problème.


Alors juste pour finir, la cerise sur le gâteau :

La requête check_003 suivante :

SELECT InstrDevis.ID_INSTRDEVIS, apDevisStatus.N_DEVISSTATUS,
apDevisStatus.devisstatus_ok
FROM (apDevisStatus RIGHT JOIN DossierEtbObj ON apDevisStatus.N_DEVISSTATUS
= DossierEtbObj.dossetbobj_etat) INNER JOIN InstrDevis ON
DossierEtbObj.ID_DOSSETBOBJ = InstrDevis.IDR_DOSSETBOBJ

Cette requête est exactement la même que test_003
mais elle ne filtre pas et elle affiche les champs pour vérification
Cette requête check_003 renvoie 10000 enregistrement avec N_DEVISSTATUS à
NULL partout (normal, puisqu'il n'y a AUCUN enregistrement dans la table
apDevisStatus), mais devisstatus_ok à 0 (zéro) partout.

Alors d'où sort ce zéro dans le champ devisstatus_ok ???

Note : pour observer le résultat de la requête check_003,
dans les propriétés du champ devisstatus_ok
j'ai enlevé le format "oui/non" et l'affichage du contrôle "case à cocher"

Donc :
Sous certaines conditions, MS Jet peut comprendre qu'un booléen absent vaut
NULL.
Sous d'autres, il ne peut pas estimer qu'un Booléen puisse valoir autre
chose que 0 ou -1.

Inutile de dire qu'une solution serait de changer le type de données du
champ devisstatus_ok en numérique entier (dans ce cas, effectivement,
test_0003 renvoie les enregistrement, même s'il y en a 10000).

Je vous remercie de votre attention,

LiR

"Sylvain Lafontaine" a écrit :

> Premièrement, vous devriez aussi nous donner quelques exemples de lignes de
> data afin que tout le monde puisse reproduire à l'identique votre problème
> (le nombre minimum de lignes requises si possible et si vous êtes capable de
> le faire, sous le format de requête INSERT).
>
> Deuxièmement, comme vous utilisez des RIGHT JOIN sous Access, il faut
> peut-être pas trop chercher à comprendre. Probablement que sur SQL-Server,
> vous obtiendrez le résultat désiré.
>
> Aussi, les RIGHT JOIN sont plus difficiles à lire et à interpréter que les
> LEFT JOIN; vous devriez arrêter d'utiliser des RIGHT JOIN et utiliser
> exclusivement des LEFT JOIN. Il est également possible qu'un utilisant un
> Left Join à la place d'un Right Join qu'Access va vous donner le résultat
> voulu. Avec JET, on ne sait jamais.
>
> --
> Sylvain Lafontaine, ing.
> MVP pour « Windows Live Platform »
> Courriel: sylvain aei ca (remplissez les blancs, svp.)
> Consultant indépendant et programmation à distance pour Access et
> SQL-Server.
>
>
> "LiR" wrote in message
> news:
> > Bonjour,
> >
> > Voici le contenu exhaustif des objets de ma base (3 tables et 2 requêtes)
> >
> > TABLE : apDevisStatus
> > -------------------------
> > N_DEVISSTATUS : Entier long (PRIMARY_KEY)
> > devisstatus_label : Texte(32)
> > devisstatus_ok : Oui/Non
> >
> > TABLE : DossierEtbObj
> > -------------------------
> > ID_DOSSETBOBJ : NuméroAuto (PRIMARY_KEY)
> > dossetbobj_etat : Entier long
> >
> > TABLE : InstrDevis
> > --------------------
> > ID_INSTRDEVIS : Entier long (PRIMARY_KEY)
> > IDR_DOSSETBOBJ : Entier long
> > devs_date : Date/Heure
> >
> > REQUÊTE : test_0003
> > ------------------------
> > SELECT InstrDevis.ID_INSTRDEVIS
> > FROM (apDevisStatus RIGHT JOIN DossierEtbObj ON
> > apDevisStatus.N_DEVISSTATUS = DossierEtbObj.dossetbobj_etat) INNER JOIN
> > InstrDevis ON DossierEtbObj.ID_DOSSETBOBJ = InstrDevis.IDR_DOSSETBOBJ
> > WHERE (((apDevisStatus.devisstatus_ok)=True Or
> > (apDevisStatus.devisstatus_ok) Is Null));
> >
> > REQUÊTE : test_0004
> > ------------------------
> > SELECT InstrDevis.ID_INSTRDEVIS
> > FROM (apDevisStatus RIGHT JOIN DossierEtbObj ON
> > apDevisStatus.N_DEVISSTATUS = DossierEtbObj.dossetbobj_etat) INNER JOIN
> > InstrDevis ON DossierEtbObj.ID_DOSSETBOBJ = InstrDevis.IDR_DOSSETBOBJ
> > WHERE (((apDevisStatus.devisstatus_ok)=True Or
> > (apDevisStatus.devisstatus_ok) Is Null) AND ((InstrDevis.ID_INSTRDEVIS) Is
> > Not Null));
> >
> >
> > Il n'y a absolument rien d'autre dans ma base en dehors de ces 3 tables et
> > ces 2 requêtes
> > Ni autre table (sauf les tables système, évidemment), ni autre requête, ni
> > formulaire, ni état, bi module VBA, ni page de données, ni macro... rien.
> >
> > La requête test_003 ne retourne aucun enregistrement
> > La requête test_003 ne retourne plusieurs enregistrements
> >
> > Comme vous pouvez le voir, la seule différence entre les 2 requêtes est
> > que test_004 a une condition de plus dans la clause WHERE
> > Cette condition est : AND ((InstrDevis.ID_INSTRDEVIS) Is Not Null))
> >
> > Le fait est que, mathématiquement, il est impossible que la requête
> > test_004 retourne plus de résultats que test_003
> > Pour la simple et bonne raison que mathématiquement (A AND B AND C) peut
> > être VRAI uniquement si (A AND B) est VRAI!
> >
> > Si vous reproduisez ma base à partir du modèle ci-dessus, elle
> > fonctionnera, fort heureusement correctement.
> > Le problème constaté concerne ma base, qui semble être endommagée...
> >
> > Seulement j'ai vérifié les index, clés primaires, contraintes....
> > J'ai compacté, importé, recompacté...
> > Rien à faire.
> > Je n'arrive pas à mettre la main sur le petit grain de sel qui fait
> > dérailler ma base.
> > A moins que ce soit un immense rocher (comme toujours, plus c'est gros...)
> >
> >
> > "Sylvain Lafontaine" a écrit dans le
> > message de news:
> >> Peut-être que si vous nous montreriez votre requête SQL - avec si
> >> possible le détail pertinent des tables et des données - on pourrait tous
> >> ensemble regarder cela et trouver où se trouve votre erreur et réduire
> >> votre étonnement à un niveau plus acceptable.
> >>
> >> --
> >> Sylvain Lafontaine, ing.
> >> MVP pour « Windows Live Platform »
> >> Courriel: sylvain aei ca (remplissez les blancs, svp.)
> >> Consultant indépendant et programmation à distance pour Access et
> >> SQL-Server.
> >>
> >>
> >> "LiR" wrote in message
> >> news:
> >>> Bonjour à tous,
> >>>
> >>> Je crée une requête Sélection dans Access XP SP3.
> >>> Cette requête repose sur une requête et 3 tables, liées par des
> >>> jointures, mais peu importe en fait.
> >>>
> >>> 1.
> >>> Je mets une condition sur un champ d'une des tables
> >>> La requête me renvoie alors zéro enregistrement
> >>>
> >>> 2.
> >>> J'ajoute une seconde condition sur un autre champ d'une autre table de
> >>> la requête
> >>> Cette condition est ajoutée sur la même ligne q'en 1., donc elle est
> >>> liée par AND à la première condition
> >>> La requête me renvoie plusieurs enregistrements
> >>>
> >>> Ce comportement est, vous en conviendrez, tout simplement impossible
> >>> théoriquement.
> >>>
> >>> Pour l'info (mais cela n'a aucun effet sur le principe) :
> >>> Condition 1 sur le champ 1 : Vrai Ou Est Null
> >>> Condition 2 sur le champ 1 : <>0
> >>>
> >>> A noter, pour s'étonner encore un peu, que si je mets comme condition 2
> >>> : >0
> >>> Alors la requête, à nouveau, me retourne zéro enregistrement
> >>>
> >>> Quelqu'un saurait d'où peut venir un comportement aussi catastrophique?
> >>
> >>
> >
>
>
>


Avatar
LiR
Bonjour,

Je vous remercie de vous être penché sur ma question

En fait, TRUE et FALSE existent tout à fait en SQL.
Ce ne sont pas vraiment des constantes, mais plutôt des mots-clés.
Remplacer True par -1 et False par 0 ne change rien dans mes requêtes
(d'ailleurs ça ne change de manière générale, puisque, comme vous dites, ce
sont les mêmes valeurs)

En fait, pour un nombre, de la même manière qu'en VBA,
Jet considèrera comme Vrai toute valeur différente de 0.

La simple requête suivante permet de s'en convaincre :

SELECT True As v1, 2=True As v2;

Elle renvoie
v1 : -1
v2 : -1

Mon problème est plutôt que Jet interprèete 0 à la place de NULL
pour le champ devistatus_ok.

J'ai remarqué une chose très étrange :
Si la requête est de type Recordset dynamique, elle renvoie 0 pour
devistatus_ok
Si la requête est de type Instantané, elle renvoie bien NULL pour
devistatus_ok

Finalement, j'ai simplifié la condition en enlevant le True :
Cela ne change rien, la requête suivante ne renvoie aucun enregistrement.

Requête test_005 :

SELECT InstrDevis.ID_INSTRDEVIS
FROM (apDevisStatus
RIGHT JOIN DossierEtbObj
ON apDevisStatus.N_DEVISSTATUS = DossierEtbObj.dossetbobj_etat)
INNER JOIN InstrDevis
ON DossierEtbObj.ID_DOSSETBOBJ = InstrDevis.IDR_DOSSETBOBJ
WHERE (((apDevisStatus.devisstatus_ok) Is Null));



"Dragan" a écrit :

Bonjour LiR,
il n'y a aucun problème. Les valeurs TRUE et FALSE sont en fait des
constantes de programmation pour un entier long, sous VBA access TRUE = -1 et
FALSE = 0; ces constantes n'existent pas sous SQL. Il faut donc dans une
requête les remplacer par leur valeur.
En clair, il faut juste remplacer :
devisstatus_ok=true :
devisstatus_ok=-1 ou (devistatus_ok<>0 AND NOT devisstatus_ok IS NULL)
devisstatus_okúlse :
devistatus_ok=0 ou (devistatus_ok<>-1 AND NOT devisstatus_ok IS NULL)



"LiR" a écrit :

> Bonjour,
>
> Voici les données
>
>
> TABLE : apDevisStatus
> -------------------------
> C'est simple : aucun enregistrement
>
>
> TABLE : DossierEtbObj
> -------------------------
>
> 10000 enregistrements, avec :
> ID_DOSSETBOBJ : de 1 à 10000
> dossetbobj_etat : NULL partout
>
> TABLE : InstrDevis
> --------------------
>
> 10000 enregistrements, avec :
> ID_INSTRDEVIS : de 1 à 10000
> IDR_DOSSETBOBJ : égal à ID_INSTRDEVIS
>
>
> Avec ces valeurs, la requête test_003 ne retourne aucun enregistrement
>
> Ce qui est très intéressant, c'est que si je supprime les enregistrements
> des tables DossierEtbObj et InstrDevis au dessus de 1000,
> c'est-à-dire que je garde 1000 enregistrements dans chaque table,
> avec les ID allant de 1 à 1000, alors là, Ô miracle :
> La requête test_003 renvoie.... tenez vous bien.... 1000 enregistrements
> avec ID_INSTRDEVIS allant de 1 à 1000.
> On n'en attendait pas moins d'elle, elle a été concue pour cela!
>
> Alors elle peut retourner 1000 enregistrements, mais 10000 semble être trop
> lui demander.
> J'espère que vous comprenez bien désormais l'étendue du problème.
>
>
> Alors juste pour finir, la cerise sur le gâteau :
>
> La requête check_003 suivante :
>
> SELECT InstrDevis.ID_INSTRDEVIS, apDevisStatus.N_DEVISSTATUS,
> apDevisStatus.devisstatus_ok
> FROM (apDevisStatus RIGHT JOIN DossierEtbObj ON apDevisStatus.N_DEVISSTATUS
> = DossierEtbObj.dossetbobj_etat) INNER JOIN InstrDevis ON
> DossierEtbObj.ID_DOSSETBOBJ = InstrDevis.IDR_DOSSETBOBJ
>
> Cette requête est exactement la même que test_003
> mais elle ne filtre pas et elle affiche les champs pour vérification
> Cette requête check_003 renvoie 10000 enregistrement avec N_DEVISSTATUS à
> NULL partout (normal, puisqu'il n'y a AUCUN enregistrement dans la table
> apDevisStatus), mais devisstatus_ok à 0 (zéro) partout.
>
> Alors d'où sort ce zéro dans le champ devisstatus_ok ???
>
> Note : pour observer le résultat de la requête check_003,
> dans les propriétés du champ devisstatus_ok
> j'ai enlevé le format "oui/non" et l'affichage du contrôle "case à cocher"
>
> Donc :
> Sous certaines conditions, MS Jet peut comprendre qu'un booléen absent vaut
> NULL.
> Sous d'autres, il ne peut pas estimer qu'un Booléen puisse valoir autre
> chose que 0 ou -1.
>
> Inutile de dire qu'une solution serait de changer le type de données du
> champ devisstatus_ok en numérique entier (dans ce cas, effectivement,
> test_0003 renvoie les enregistrement, même s'il y en a 10000).
>
> Je vous remercie de votre attention,
>
> LiR
>
> "Sylvain Lafontaine" a écrit :
>
> > Premièrement, vous devriez aussi nous donner quelques exemples de lignes de
> > data afin que tout le monde puisse reproduire à l'identique votre problème
> > (le nombre minimum de lignes requises si possible et si vous êtes capable de
> > le faire, sous le format de requête INSERT).
> >
> > Deuxièmement, comme vous utilisez des RIGHT JOIN sous Access, il faut
> > peut-être pas trop chercher à comprendre. Probablement que sur SQL-Server,
> > vous obtiendrez le résultat désiré.
> >
> > Aussi, les RIGHT JOIN sont plus difficiles à lire et à interpréter que les
> > LEFT JOIN; vous devriez arrêter d'utiliser des RIGHT JOIN et utiliser
> > exclusivement des LEFT JOIN. Il est également possible qu'un utilisant un
> > Left Join à la place d'un Right Join qu'Access va vous donner le résultat
> > voulu. Avec JET, on ne sait jamais.
> >
> > --
> > Sylvain Lafontaine, ing.
> > MVP pour « Windows Live Platform »
> > Courriel: sylvain aei ca (remplissez les blancs, svp.)
> > Consultant indépendant et programmation à distance pour Access et
> > SQL-Server.
> >
> >
> > "LiR" wrote in message
> > news:
> > > Bonjour,
> > >
> > > Voici le contenu exhaustif des objets de ma base (3 tables et 2 requêtes)
> > >
> > > TABLE : apDevisStatus
> > > -------------------------
> > > N_DEVISSTATUS : Entier long (PRIMARY_KEY)
> > > devisstatus_label : Texte(32)
> > > devisstatus_ok : Oui/Non
> > >
> > > TABLE : DossierEtbObj
> > > -------------------------
> > > ID_DOSSETBOBJ : NuméroAuto (PRIMARY_KEY)
> > > dossetbobj_etat : Entier long
> > >
> > > TABLE : InstrDevis
> > > --------------------
> > > ID_INSTRDEVIS : Entier long (PRIMARY_KEY)
> > > IDR_DOSSETBOBJ : Entier long
> > > devs_date : Date/Heure
> > >
> > > REQUÊTE : test_0003
> > > ------------------------
> > > SELECT InstrDevis.ID_INSTRDEVIS
> > > FROM (apDevisStatus RIGHT JOIN DossierEtbObj ON
> > > apDevisStatus.N_DEVISSTATUS = DossierEtbObj.dossetbobj_etat) INNER JOIN
> > > InstrDevis ON DossierEtbObj.ID_DOSSETBOBJ = InstrDevis.IDR_DOSSETBOBJ
> > > WHERE (((apDevisStatus.devisstatus_ok)=True Or
> > > (apDevisStatus.devisstatus_ok) Is Null));
> > >
> > > REQUÊTE : test_0004
> > > ------------------------
> > > SELECT InstrDevis.ID_INSTRDEVIS
> > > FROM (apDevisStatus RIGHT JOIN DossierEtbObj ON
> > > apDevisStatus.N_DEVISSTATUS = DossierEtbObj.dossetbobj_etat) INNER JOIN
> > > InstrDevis ON DossierEtbObj.ID_DOSSETBOBJ = InstrDevis.IDR_DOSSETBOBJ
> > > WHERE (((apDevisStatus.devisstatus_ok)=True Or
> > > (apDevisStatus.devisstatus_ok) Is Null) AND ((InstrDevis.ID_INSTRDEVIS) Is
> > > Not Null));
> > >
> > >
> > > Il n'y a absolument rien d'autre dans ma base en dehors de ces 3 tables et
> > > ces 2 requêtes
> > > Ni autre table (sauf les tables système, évidemment), ni autre requête, ni
> > > formulaire, ni état, bi module VBA, ni page de données, ni macro... rien.
> > >
> > > La requête test_003 ne retourne aucun enregistrement
> > > La requête test_003 ne retourne plusieurs enregistrements
> > >
> > > Comme vous pouvez le voir, la seule différence entre les 2 requêtes est
> > > que test_004 a une condition de plus dans la clause WHERE
> > > Cette condition est : AND ((InstrDevis.ID_INSTRDEVIS) Is Not Null))
> > >
> > > Le fait est que, mathématiquement, il est impossible que la requête
> > > test_004 retourne plus de résultats que test_003
> > > Pour la simple et bonne raison que mathématiquement (A AND B AND C) peut
> > > être VRAI uniquement si (A AND B) est VRAI!
> > >
> > > Si vous reproduisez ma base à partir du modèle ci-dessus, elle
> > > fonctionnera, fort heureusement correctement.
> > > Le problème constaté concerne ma base, qui semble être endommagée...
> > >
> > > Seulement j'ai vérifié les index, clés primaires, contraintes....
> > > J'ai compacté, importé, recompacté...
> > > Rien à faire.
> > > Je n'arrive pas à mettre la main sur le petit grain de sel qui fait
> > > dérailler ma base.
> > > A moins que ce soit un immense rocher (comme toujours, plus c'est gros...)
> > >
> > >
> > > "Sylvain Lafontaine" a écrit dans le
> > > message de news:
> > >> Peut-être que si vous nous montreriez votre requête SQL - avec si
> > >> possible le détail pertinent des tables et des données - on pourrait tous
> > >> ensemble regarder cela et trouver où se trouve votre erreur et réduire
> > >> votre étonnement à un niveau plus acceptable.
> > >>
> > >> --
> > >> Sylvain Lafontaine, ing.
> > >> MVP pour « Windows Live Platform »
> > >> Courriel: sylvain aei ca (remplissez les blancs, svp.)
> > >> Consultant indépendant et programmation à distance pour Access et
> > >> SQL-Server.
> > >>
> > >>
> > >> "LiR" wrote in message
> > >> news:
> > >>> Bonjour à tous,
> > >>>
> > >>> Je crée une requête Sélection dans Access XP SP3.
> > >>> Cette requête repose sur une requête et 3 tables, liées par des
> > >>> jointures, mais peu importe en fait.
> > >>>
> > >>> 1.
> > >>> Je mets une condition sur un champ d'une des tables
> > >>> La requête me renvoie alors zéro enregistrement
> > >>>
> > >>> 2.
> > >>> J'ajoute une seconde condition sur un autre champ d'une autre table de
> > >>> la requête
> > >>> Cette condition est ajoutée sur la même ligne q'en 1., donc elle est
> > >>> liée par AND à la première condition
> > >>> La requête me renvoie plusieurs enregistrements
> > >>>
> > >>> Ce comportement est, vous en conviendrez, tout simplement impossible
> > >>> théoriquement.
> > >>>
> > >>> Pour l'info (mais cela n'a aucun effet sur le principe) :
> > >>> Condition 1 sur le champ 1 : Vrai Ou Est Null
> > >>> Condition 2 sur le champ 1 : <>0
> > >>>
> > >>> A noter, pour s'étonner encore un peu, que si je mets comme condition 2
> > >>> : >0
> > >>> Alors la requête, à nouveau, me retourne zéro enregistrement
> > >>>
> > >>> Quelqu'un saurait d'où peut venir un comportement aussi catastrophique?
> > >>
> > >>
> > >
> >
> >
> >


Avatar
Dragan
Ok, je confirme ceux sont des constantes de définition dans tous les langages
de programmation. Dans les requêtes, il est toujours préférable d'utiliser
leur valeur.
Bon, je reconnais m'être emballé à la lecture du premier post; et ne pas
l'avoir lu correctement.
Il y a je crois quelques incohérences dans la requête; entre le RIGHT JOIN
qui est censé permettre de retourner les enregistrements de la table
DossierEtbObj quelque soit le contenu de la table apDevisStatus et la clause
WHERE qui stipule au contraire que la table apDevisStatus ne doit pas être
vide; puisque au moins un de ces champs doit répondre au critère.

En clair, la première requête telle qu'elle est construite ne peut renvoyer
que les enregistrements de apDevisStatus qui répondent au critère. Et si
cette table est vide la requête ne renvoie aucun enregitrement.






"LiR" a écrit :

Bonjour,

Je vous remercie de vous être penché sur ma question

En fait, TRUE et FALSE existent tout à fait en SQL.
Ce ne sont pas vraiment des constantes, mais plutôt des mots-clés.
Remplacer True par -1 et False par 0 ne change rien dans mes requêtes
(d'ailleurs ça ne change de manière générale, puisque, comme vous dites, ce
sont les mêmes valeurs)

En fait, pour un nombre, de la même manière qu'en VBA,
Jet considèrera comme Vrai toute valeur différente de 0.

La simple requête suivante permet de s'en convaincre :

SELECT True As v1, 2=True As v2;

Elle renvoie
v1 : -1
v2 : -1

Mon problème est plutôt que Jet interprèete 0 à la place de NULL
pour le champ devistatus_ok.

J'ai remarqué une chose très étrange :
Si la requête est de type Recordset dynamique, elle renvoie 0 pour
devistatus_ok
Si la requête est de type Instantané, elle renvoie bien NULL pour
devistatus_ok

Finalement, j'ai simplifié la condition en enlevant le True :
Cela ne change rien, la requête suivante ne renvoie aucun enregistrement.

Requête test_005 :

SELECT InstrDevis.ID_INSTRDEVIS
FROM (apDevisStatus
RIGHT JOIN DossierEtbObj
ON apDevisStatus.N_DEVISSTATUS = DossierEtbObj.dossetbobj_etat)
INNER JOIN InstrDevis
ON DossierEtbObj.ID_DOSSETBOBJ = InstrDevis.IDR_DOSSETBOBJ
WHERE (((apDevisStatus.devisstatus_ok) Is Null));



"Dragan" a écrit :

> Bonjour LiR,
> il n'y a aucun problème. Les valeurs TRUE et FALSE sont en fait des
> constantes de programmation pour un entier long, sous VBA access TRUE = -1 et
> FALSE = 0; ces constantes n'existent pas sous SQL. Il faut donc dans une
> requête les remplacer par leur valeur.
> En clair, il faut juste remplacer :
> devisstatus_ok=true :
> devisstatus_ok=-1 ou (devistatus_ok<>0 AND NOT devisstatus_ok IS NULL)
> devisstatus_okúlse :
> devistatus_ok=0 ou (devistatus_ok<>-1 AND NOT devisstatus_ok IS NULL)
>
>
>
> "LiR" a écrit :
>
> > Bonjour,
> >
> > Voici les données
> >
> >
> > TABLE : apDevisStatus
> > -------------------------
> > C'est simple : aucun enregistrement
> >
> >
> > TABLE : DossierEtbObj
> > -------------------------
> >
> > 10000 enregistrements, avec :
> > ID_DOSSETBOBJ : de 1 à 10000
> > dossetbobj_etat : NULL partout
> >
> > TABLE : InstrDevis
> > --------------------
> >
> > 10000 enregistrements, avec :
> > ID_INSTRDEVIS : de 1 à 10000
> > IDR_DOSSETBOBJ : égal à ID_INSTRDEVIS
> >
> >
> > Avec ces valeurs, la requête test_003 ne retourne aucun enregistrement
> >
> > Ce qui est très intéressant, c'est que si je supprime les enregistrements
> > des tables DossierEtbObj et InstrDevis au dessus de 1000,
> > c'est-à-dire que je garde 1000 enregistrements dans chaque table,
> > avec les ID allant de 1 à 1000, alors là, Ô miracle :
> > La requête test_003 renvoie.... tenez vous bien.... 1000 enregistrements
> > avec ID_INSTRDEVIS allant de 1 à 1000.
> > On n'en attendait pas moins d'elle, elle a été concue pour cela!
> >
> > Alors elle peut retourner 1000 enregistrements, mais 10000 semble être trop
> > lui demander.
> > J'espère que vous comprenez bien désormais l'étendue du problème.
> >
> >
> > Alors juste pour finir, la cerise sur le gâteau :
> >
> > La requête check_003 suivante :
> >
> > SELECT InstrDevis.ID_INSTRDEVIS, apDevisStatus.N_DEVISSTATUS,
> > apDevisStatus.devisstatus_ok
> > FROM (apDevisStatus RIGHT JOIN DossierEtbObj ON apDevisStatus.N_DEVISSTATUS
> > = DossierEtbObj.dossetbobj_etat) INNER JOIN InstrDevis ON
> > DossierEtbObj.ID_DOSSETBOBJ = InstrDevis.IDR_DOSSETBOBJ
> >
> > Cette requête est exactement la même que test_003
> > mais elle ne filtre pas et elle affiche les champs pour vérification
> > Cette requête check_003 renvoie 10000 enregistrement avec N_DEVISSTATUS à
> > NULL partout (normal, puisqu'il n'y a AUCUN enregistrement dans la table
> > apDevisStatus), mais devisstatus_ok à 0 (zéro) partout.
> >
> > Alors d'où sort ce zéro dans le champ devisstatus_ok ???
> >
> > Note : pour observer le résultat de la requête check_003,
> > dans les propriétés du champ devisstatus_ok
> > j'ai enlevé le format "oui/non" et l'affichage du contrôle "case à cocher"
> >
> > Donc :
> > Sous certaines conditions, MS Jet peut comprendre qu'un booléen absent vaut
> > NULL.
> > Sous d'autres, il ne peut pas estimer qu'un Booléen puisse valoir autre
> > chose que 0 ou -1.
> >
> > Inutile de dire qu'une solution serait de changer le type de données du
> > champ devisstatus_ok en numérique entier (dans ce cas, effectivement,
> > test_0003 renvoie les enregistrement, même s'il y en a 10000).
> >
> > Je vous remercie de votre attention,
> >
> > LiR
> >
> > "Sylvain Lafontaine" a écrit :
> >
> > > Premièrement, vous devriez aussi nous donner quelques exemples de lignes de
> > > data afin que tout le monde puisse reproduire à l'identique votre problème
> > > (le nombre minimum de lignes requises si possible et si vous êtes capable de
> > > le faire, sous le format de requête INSERT).
> > >
> > > Deuxièmement, comme vous utilisez des RIGHT JOIN sous Access, il faut
> > > peut-être pas trop chercher à comprendre. Probablement que sur SQL-Server,
> > > vous obtiendrez le résultat désiré.
> > >
> > > Aussi, les RIGHT JOIN sont plus difficiles à lire et à interpréter que les
> > > LEFT JOIN; vous devriez arrêter d'utiliser des RIGHT JOIN et utiliser
> > > exclusivement des LEFT JOIN. Il est également possible qu'un utilisant un
> > > Left Join à la place d'un Right Join qu'Access va vous donner le résultat
> > > voulu. Avec JET, on ne sait jamais.
> > >
> > > --
> > > Sylvain Lafontaine, ing.
> > > MVP pour « Windows Live Platform »
> > > Courriel: sylvain aei ca (remplissez les blancs, svp.)
> > > Consultant indépendant et programmation à distance pour Access et
> > > SQL-Server.
> > >
> > >
> > > "LiR" wrote in message
> > > news:
> > > > Bonjour,
> > > >
> > > > Voici le contenu exhaustif des objets de ma base (3 tables et 2 requêtes)
> > > >
> > > > TABLE : apDevisStatus
> > > > -------------------------
> > > > N_DEVISSTATUS : Entier long (PRIMARY_KEY)
> > > > devisstatus_label : Texte(32)
> > > > devisstatus_ok : Oui/Non
> > > >
> > > > TABLE : DossierEtbObj
> > > > -------------------------
> > > > ID_DOSSETBOBJ : NuméroAuto (PRIMARY_KEY)
> > > > dossetbobj_etat : Entier long
> > > >
> > > > TABLE : InstrDevis
> > > > --------------------
> > > > ID_INSTRDEVIS : Entier long (PRIMARY_KEY)
> > > > IDR_DOSSETBOBJ : Entier long
> > > > devs_date : Date/Heure
> > > >
> > > > REQUÊTE : test_0003
> > > > ------------------------
> > > > SELECT InstrDevis.ID_INSTRDEVIS
> > > > FROM (apDevisStatus RIGHT JOIN DossierEtbObj ON
> > > > apDevisStatus.N_DEVISSTATUS = DossierEtbObj.dossetbobj_etat) INNER JOIN
> > > > InstrDevis ON DossierEtbObj.ID_DOSSETBOBJ = InstrDevis.IDR_DOSSETBOBJ
> > > > WHERE (((apDevisStatus.devisstatus_ok)=True Or
> > > > (apDevisStatus.devisstatus_ok) Is Null));
> > > >
> > > > REQUÊTE : test_0004
> > > > ------------------------
> > > > SELECT InstrDevis.ID_INSTRDEVIS
> > > > FROM (apDevisStatus RIGHT JOIN DossierEtbObj ON
> > > > apDevisStatus.N_DEVISSTATUS = DossierEtbObj.dossetbobj_etat) INNER JOIN
> > > > InstrDevis ON DossierEtbObj.ID_DOSSETBOBJ = InstrDevis.IDR_DOSSETBOBJ
> > > > WHERE (((apDevisStatus.devisstatus_ok)=True Or
> > > > (apDevisStatus.devisstatus_ok) Is Null) AND ((InstrDevis.ID_INSTRDEVIS) Is
> > > > Not Null));
> > > >
> > > >
> > > > Il n'y a absolument rien d'autre dans ma base en dehors de ces 3 tables et
> > > > ces 2 requêtes
> > > > Ni autre table (sauf les tables système, évidemment), ni autre requête, ni
> > > > formulaire, ni état, bi module VBA, ni page de données, ni macro... rien.
> > > >
> > > > La requête test_003 ne retourne aucun enregistrement
> > > > La requête test_003 ne retourne plusieurs enregistrements
> > > >
> > > > Comme vous pouvez le voir, la seule différence entre les 2 requêtes est
> > > > que test_004 a une condition de plus dans la clause WHERE
> > > > Cette condition est : AND ((InstrDevis.ID_INSTRDEVIS) Is Not Null))
> > > >
> > > > Le fait est que, mathématiquement, il est impossible que la requête
> > > > test_004 retourne plus de résultats que test_003
> > > > Pour la simple et bonne raison que mathématiquement (A AND B AND C) peut
> > > > être VRAI uniquement si (A AND B) est VRAI!
> > > >
> > > > Si vous reproduisez ma base à partir du modèle ci-dessus, elle
> > > > fonctionnera, fort heureusement correctement.
> > > > Le problème constaté concerne ma base, qui semble être endommagée...
> > > >
> > > > Seulement j'ai vérifié les index, clés primaires, contraintes....
> > > > J'ai compacté, importé, recompacté...
> > > > Rien à faire.
> > > > Je n'arrive pas à mettre la main sur le petit grain de sel qui fait
> > > > dérailler ma base.
> > > > A moins que ce soit un immense rocher (comme toujours, plus c'est gros...)
> > > >
> > > >
> > > > "Sylvain Lafontaine" a écrit dans le
> > > > message de news:
> > > >> Peut-être que si vous nous montreriez votre requête SQL - avec si
> > > >> possible le détail pertinent des tables et des données - on pourrait tous
> > > >> ensemble regarder cela et trouver où se trouve votre erreur et réduire
> > > >> votre étonnement à un niveau plus acceptable.
> > > >>
> > > >> --
> > > >> Sylvain Lafontaine, ing.
> > > >> MVP pour « Windows Live Platform »
> > > >> Courriel: sylvain aei ca (remplissez les blancs, svp.)
> > > >> Consultant indépendant et programmation à distance pour Access et
> > > >> SQL-Server.
> > > >>
> > > >>
> > > >> "LiR" wrote in message
> > > >> news:
> > > >>> Bonjour à tous,
> > > >>>
> > > >>> Je crée une requête Sélection dans Access XP SP3.
> > > >>> Cette requête repose sur une requête et 3 tables, liées par des
> > > >>> jointures, mais peu importe en fait.
> > > >>>
> > > >>> 1.
> > > >>> Je mets une condition sur un champ d'une des tables
> > > >>> La requête me renvoie alors zéro enregistrement
> > > >>>
> > > >>> 2.
> > > >>> J'ajoute une seconde condition sur un autre champ d'une autre table de
> > > >>> la requête
> > > >>> Cette condition est ajoutée sur la même ligne q'en 1., donc elle est
> > > >>> liée par AND à la première condition
> > > >>> La requête me renvoie plusieurs enregistrements
> > > >>>
> > > >>> Ce comportement est, vous en conviendrez, tout simplement impossible
> > > >>> théoriquement.
> > > >>>
> > > >>> Pour l'info (mais cela n'a aucun effet sur le principe) :
> > > >>> Condition 1 sur le champ 1 : Vrai Ou Est Null
> > > >>> Condition 2 sur le champ 1 : <>0
> > > >>>
> > > >>> A noter, pour s'étonner encore un peu, que si je mets comme condition 2
> > > >>> : >0
> > > >>> Alors la requête, à nouveau, me retourne zéro enregistrement
> > > >>>
> > > >>> Quelqu'un saurait d'où peut venir un comportement aussi catastrophique?
> > > >>
> > > >>
> > > >
> > >
> > >
> > >


1 2 3