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 26/01/2012, 23h23   #1
Invité de passage
 
Inscription : mars 2008
Messages : 23
Détails du profil
Informations forums :
Inscription : mars 2008
Messages : 23
Points : 4
Points : 4
Par défaut Erreur de requête not in sur deux tables

Bonjour a tous,

Je me permets d écrire car je n ai pas trouvé de problème similaire au miens ...
Je m explique :

J ai deux tables dans une base " assez bien utilisé par plusieurs utilisateurs " j ai une requete delete from avec une condition not in ... cependant de temps en temps sans expliquation j ai ma requête qui " ne va pas bien consulter la deuxième dépendante du not in et va donc me supprimer des donnes que je ne voudrais pas.

Exemple : delete from tablea where c_client not in (select c_client from tableb)

Parfois cette requête va supprimer des éléments de tablea qui sont bien dans tableb

La question est donc, pourquoi ... est ce que parce que tableb est occupé au moment de la requête ? Et surtout il y a t il un moyen d empêcher cela sans toucher a la requête ? Paramètre dans sql serveur ?

Merci de votre aide
neptunia est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/01/2012, 23h51   #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
A priori je pense que vous connaissez mal le langage SQL...

En effet, avec NOT IN, si la sous requête retourne des NULL, alors le prédicat vaut faux.

DEMONSTRATION...


Code :
1
2
3
4
5
CREATE TABLE T1 (C1 INT);
INSERT INTO T1 VALUES (1), (2), (3), (4);
 
CREATE TABLE T2 (C2 INT);
INSERT INTO T2 VALUES (2), (4), (6);
Code :
1
2
DELETE FROM T1
WHERE C1 NOT IN (SELECT C2 FROM T2);
Code :
1
2
3
4
5
6
SELECT * FROM T1;
 
C1
-----------
2
4

--> ce qui est le résultat que vous attendiez certainement...

Code :
1
2
3
4
5
 
DELETE FROM T1;
INSERT INTO T1 VALUES (1), (2), (3), (4);
 
INSERT INTO T2 VALUES (NULL);
Code :
1
2
3
 
DELETE FROM T1
WHERE C1 NOT IN (SELECT C2 FROM T2);
Code :
1
2
3
4
5
6
7
8
SELECT * FROM T1;
 
C1
-----------
1
2
3
4
--> ce qui est exact, mais auquel vous ne vous attendiez pas !

Bref, apprenez le SQL... Mon site web, comme mon bouquin est là pour vous aider !

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 10
Vieux 27/01/2012, 10h37   #3
Invité de passage
 
Inscription : mars 2008
Messages : 23
Détails du profil
Informations forums :
Inscription : mars 2008
Messages : 23
Points : 4
Points : 4
Bonjour, et merci pour ton aide.

Je ne pense pas être une experte, mais une utilisatrice normalement expérimentée.

J'ai donc mal du m'exprimer pour exposer mon problème.

Voici donc la rêquete en question

Code :
DELETE FROM  stock_reserve  WHERE date_liv<'20111020'  AND stock_reserve.n_cde NOT IN (SELECT ent_cde.n_cde FROM ent_cde WHERE stock_reserve.n_cde=ent_cde.n_cde AND c_etat_cde='C') AND c_trf<>'O'
Ce qui se passe, de temps en temps, cette requête va mal faire son travail, et supprimer des valeurs qui sont pourtant bien présente sur

Code :
SELECT ent_cde.n_cde FROM ent_cde WHERE stock_reserve.n_cde=ent_cde.n_cde AND c_etat_cde='C'
Je me suis demandée, si ce n'était pas parce que la table ent_cde représente 140 924 lignes, et qu'elle est souvent select / update / insert
est il donc possible que ma premiere requete n'arrive pas à consulter de temps en temps ent_cde et donc .. va supprimer des éléments de stock_reserve sans vraiment attendre la fin du résultat de ent_cde

Merci encore de votre aide.
neptunia est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/01/2012, 11h06   #4
Membre Expert
 
Inscription : août 2009
Messages : 779
Détails du profil
Informations forums :
Inscription : août 2009
Messages : 779
Points : 1 098
Points : 1 098
Citation:
Envoyé par neptunia Voir le message
Je me suis demandée, si ce n'était pas parce que la table ent_cde représente 140 924 lignes, et qu'elle est souvent select / update / insert
est il donc possible que ma premiere requete n'arrive pas à consulter de temps en temps ent_cde et donc .. va supprimer des éléments de stock_reserve sans vraiment attendre la fin du résultat de ent_cde

Merci encore de votre aide.
"Sans attendre", non. Par contre, il se peut qu'un autre traitement, en particulier s'il est itératif, rajoute une ligne dans ent_cde APRÈS que la suppression ait été faite.
Rei Ichido est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/01/2012, 11h24   #5
Invité de passage
 
Inscription : mars 2008
Messages : 23
Détails du profil
Informations forums :
Inscription : mars 2008
Messages : 23
Points : 4
Points : 4
Hummm ... merci bien de ta réponse ...
Certain ? qu'aucun paramètre serveur pourrait mettre un délai timeout ?! et que du coups il n'arrive pas à lire dans un délai " normal " execute la requete sans lire la table ent_cde ... ?!

Le pire étant que ce n'est pas la seule requete avec un not in qui me fait ce genre de problème ... ='( ce qui n'est pas logique étant qu'il n'y a pas de répétition bien définie ... cela arrive de temps en temps parfois 1 fois par mois, parfois rien durant 2 mois, parfois 4 fois sur un mois ...
neptunia est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/01/2012, 11h37   #6
Membre Expert
 
Inscription : août 2009
Messages : 779
Détails du profil
Informations forums :
Inscription : août 2009
Messages : 779
Points : 1 098
Points : 1 098
S'il y a un timeout, cela déclenchera une exception qui portera sur l'intégralité de la requête, et donc aucune suppression n'aura été effectuée.
Rei Ichido est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/01/2012, 11h41   #7
Invité de passage
 
Inscription : mars 2008
Messages : 23
Détails du profil
Informations forums :
Inscription : mars 2008
Messages : 23
Points : 4
Points : 4
Hummm ... ok !

Bon quel serait le moyen pour " vérifier " ce qu'il se passe exactement ? Autre que lancer manuellement un profiler ... ?
neptunia est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/01/2012, 11h48   #8
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
Si votre sous requête :
Code :
SELECT ent_cde.n_cde FROM ent_cde WHERE stock_reserve.n_cde=ent_cde.n_cde AND c_etat_cde='C'
Renvoi un NULL dans ent_cde.n_cde
Alors NOT IN est faux, donc tout est traité.

Vérifiez que vous n'avez pas de temps à autre un ent_cde.n_cde NULL !

Remplacez le NOT IN pas un NOT EXISTS corrélé.

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 01
Vieux 27/01/2012, 11h56   #9
Invité de passage
 
Inscription : mars 2008
Messages : 23
Détails du profil
Informations forums :
Inscription : mars 2008
Messages : 23
Points : 4
Points : 4
Hum Hum ...
Je ne peux modifier la requete hélas ...
Il n'est normalement pas pensable d'avoir une valeur null dans n_cde ...
mais pouvons nous avec un profiler automatique qui sauvegarde jour / jour avec un résultat des requetes ? enfin ... un moyen tout simplement de pister l'erreur ?!

Merci en tout cas de votre aide.
neptunia est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/01/2012, 12h02   #10
Membre Expert
 
Inscription : août 2009
Messages : 779
Détails du profil
Informations forums :
Inscription : août 2009
Messages : 779
Points : 1 098
Points : 1 098
Citation:
Envoyé par SQLpro Voir le message
Si votre sous requête :
Code :
SELECT ent_cde.n_cde FROM ent_cde WHERE stock_reserve.n_cde=ent_cde.n_cde AND c_etat_cde='C'
Renvoi un NULL dans ent_cde.n_cde
Alors NOT IN est faux, donc tout est traité.
Vu la requête, si le NOT IN est faux, il n'y aura aucune ligne supprimée.
Or là, le problème c'est qu'il y a des lignes supprimées qui ne devraient pas l'être.

Edit : de toute façon, NULL n'est pas une valeur qui peut être retournée par cette requête ; elle sélectionne ent_cde.n_cde et il y a une condition d'égalité sur cette valeur.
Rei Ichido est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/01/2012, 12h11   #11
Membre expérimenté
 
Avatar de nsanabi
 
Homme nabil nayd
Inscription : septembre 2003
Messages : 566
Détails du profil
Informations personnelles :
Nom : Homme nabil nayd

Informations forums :
Inscription : septembre 2003
Messages : 566
Points : 596
Points : 596
Envoyer un message via MSN à nsanabi
Citation:
Envoyé par SQLpro Voir le message
Si votre sous requête :
Code :
SELECT ent_cde.n_cde FROM ent_cde WHERE stock_reserve.n_cde=ent_cde.n_cde AND c_etat_cde='C'
Renvoi un NULL dans ent_cde.n_cde
Alors NOT IN est faux, donc tout est traité.
(x not in (null)) renvoi false ??!!
nsanabi est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/01/2012, 12h18   #12
Membre Expert
 
Inscription : août 2009
Messages : 779
Détails du profil
Informations forums :
Inscription : août 2009
Messages : 779
Points : 1 098
Points : 1 098
Citation:
Envoyé par nsanabi Voir le message
(x not in (null)) renvoi false ??!!
Oui.
x NOT IN (null), ce n'est jamais que x <> null, dont le résultat est unknown, ce qui est finalement converti en false.
D'ailleurs, NOT (x NOT IN (null)) est aussi false.
Rei Ichido est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/01/2012, 09h41   #13
Invité de passage
 
Inscription : mars 2008
Messages : 23
Détails du profil
Informations forums :
Inscription : mars 2008
Messages : 23
Points : 4
Points : 4
Merci de vos réponses, j'aimerai savoir cependant, si ma précédente question est possible :
Citation:
mais pouvons nous avec un profiler automatique qui sauvegarde jour / jour avec un résultat des requetes ? enfin ... un moyen tout simplement de pister l'erreur ?!
Merci bien !
neptunia est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/01/2012, 15h36   #14
Membre Expert
 
Inscription : août 2009
Messages : 779
Détails du profil
Informations forums :
Inscription : août 2009
Messages : 779
Points : 1 098
Points : 1 098
Vous pourriez mettre temporairement en place une insertion dans une table de log, avant et après votre requête ... Cela peut s'avérer consommateur (de temps CPU et de mémoire), cela dit.

Vous devriez surtout tracer les modifications sur la table stock_reserve, vu la requête le seul moyen de générer votre problème c'est qu'elle soit modifiée après le DELETE, provoquant une incohérence des données.
Rei Ichido 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 20h44.


 
 
 
 
Partenaires

Hébergement Web