IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

MS SQL Server Discussion :

Index et science fiction


Sujet :

MS SQL Server

  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2008
    Messages
    698
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Boutique - Magasin

    Informations forums :
    Inscription : Octobre 2008
    Messages : 698
    Points : 586
    Points
    586
    Par défaut Index et science fiction
    Bonjour à tous,

    je pose la question avant de restaurer ma base de données...

    Je planche sur un bug depuis hier soir, j'ai une requête qui ne donne pas le même résultat depuis management studio et depuis mon appli.
    Il faut savoir que j'utilise windev (ne me lancez pas de cailloux svp ) qui pose son lot de problèmes, mais je crois que cette fois ça ne vient pas de là.

    J'ai essayé ma requête sur toutes mes bases de données et elle ne se lance pas car il manque des tables, ce qui prouve que je travaille bien sur la même base entre l'application et management studio.

    C'est comme si depuis mon application il manquait les paramètres d'une jointure. En faisant un peu de débug j'ai fait afficher la requête juste avant l’exécution pour être sûr qu'elle n'est pas biaisée par mon code source ce qui n'est pas le cas, car un simple copié collé fonctionne sous SSMS mais pas dans mon programme.

    Plus étrange encore lorsque je crée un index sur ma table, ma requête ne donne plus de résultat ni sur SSMS ni dans mon programme.

    Quelqu'un a une piste?
    Je voudrais profiter de l’expérience pour le jour où ça m'arrive en production.

    Merci a bientôt

    PS: Comme d'habitude, secret professionnel bla bla bla je ne peux pas donner trop d'information.

  2. #2
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    bonjour,

    Citation Envoyé par Donpi Voir le message
    j'ai une requête qui ne donne pas le même résultat depuis management studio et depuis mon appli.
    C'est à dire ? elle fonctionne dans les deux cas mais ne renvoient pas les même résultats.

    Elle n'est peut-être pas deterministe. contient-elle une clause TOP ? ou autre...

    J'ai essayé ma requête sur toutes mes bases de données et elle ne se lance pas car il manque des tables, ce qui prouve que je travaille bien sur la même base entre l'application et management studio.

    C'est comme si depuis mon application il manquait les paramètres d'une jointure. En faisant un peu de débug j'ai fait afficher la requête juste avant l’exécution pour être sûr qu'elle n'est pas biaisée par mon code source ce qui n'est pas le cas, car un simple copié collé fonctionne sous SSMS mais pas dans mon programme.
    Le mieux serait de mettre une trace pour voir exactement ce qu'il se passe.

    Plus étrange encore lorsque je crée un index sur ma table, ma requête ne donne plus de résultat ni sur SSMS ni dans mon programme.
    Ne répond pas ? ou aucune ligne dans le résultat ?

  3. #3
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2008
    Messages
    698
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Boutique - Magasin

    Informations forums :
    Inscription : Octobre 2008
    Messages : 698
    Points : 586
    Points
    586
    Par défaut
    Dans l'ordre :
    - SSMS donne 3 lignes de résultat et mon programme en donne 5
    - Il y a un Top 1 dans un Cross Apply
    - Je vais essayé ça dans la matinée
    - Aucune ligne de résultat, dés que je supprime l'index j'ai a nouveau de lignes.
    J'ai essayer de faire un rebuild / réindex etc.. sans succès...
    Je peu même le faire à répétition, création, suppression, création, suppression.
    Toujours le même résultat, sans l'index j'ai un résultat, avec j'ai rien...

    J'ai aussi essayé de sortit mon code et de le mettre dans un programme vierge, mais le résultat est identique.

  4. #4
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    En effet, je pense que la première chose à faire, c'est la trace. ça ôtera certains doutes : l'erreur grosse comme une maison cachée par le guidon dans lequel vous avez la tête...

    Pour le TOP, y a-t-il un ORDER BY, et est-il suffisant pour assurer le déterminisme du résultat ? Dans le doute, essayez de l'enlever.

    Quand à cette histoire d'index... je sèche ! Pour info, avez-vous des vues indexées sur les tables sur lesquelles porte votre requête ?

    Sans avoir au moins la requête en question, on est un peu (beaucoup) dans le brouillard... Ne pouvez-vous pas l'anonymiser pour la poster ?

  5. #5
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2008
    Messages
    698
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Boutique - Magasin

    Informations forums :
    Inscription : Octobre 2008
    Messages : 698
    Points : 586
    Points
    586
    Par défaut
    Voilà, j'ai changer les noms de tables et enlevé tout ce qui n'est pas indispensable.

    Le but est de ressortir les stock minimaux par genre de boutique.
    En sachant que je peux avoir un stock différent par boutique et que si j'ai plus de lignes que le nombre de genre le cas est géré dans l'application.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    SELECT DISTINCT G.GenreBoutique,S.QteMin
    from Commande C
    inner join StockMin S on S.IdArticle=C.IdArticle
    cross apply ( 
    		Select top 1 IdGenre
    		from HistoriqueDesGenres Hin 
    		WHERE Hin.IdBoutique = S.IdBoutique
    			and Hin.DateValeure<= C.DateValeure
    		order by Hin.DateValeure desc
    	)  H
    inner join Genre G on G.IdGenre=H.IdGenre
    WHERE C.IdCommande=123456

  6. #6
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 947
    Points : 5 846
    Points
    5 846
    Par défaut
    Quelle est le type de donnée de datevaleur, peut il y avoir plusieurs datevaleur identiques par IdBoutique ?
    La colonne IdGenre de la table HistoriqueDesGenres est elle déclarée comme NOT NULL ?

  7. #7
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2008
    Messages
    698
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Boutique - Magasin

    Informations forums :
    Inscription : Octobre 2008
    Messages : 698
    Points : 586
    Points
    586
    Par défaut
    Citation Envoyé par skuatamad Voir le message
    Quelle est le type de donnée de datevaleur, peut il y avoir plusieurs datevaleur identiques par IdBoutique ?
    La colonne IdGenre de la table HistoriqueDesGenres est elle déclarée comme NOT NULL ?
    DateValeur est un datetime avec les heures à 0 (une sorte de date castée en datetime)

    Il n'y a qu'une date par IdBoutique. Si il devait y en avoir une deuxième, le record existant serait modifié pour n'en avoir qu'une.

    Dans HistoriqueDesGenre j'ai une variante pire que le nullable. Les personnes qui ont développé la version original étaient très porté sur Windev où le NULL n'existe pas. J'ai des Id à 0. Mais ils sont sensé être ignoré par la pseudo jointure du cross apply.

  8. #8
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 947
    Points : 5 846
    Points
    5 846
    Par défaut
    Citation Envoyé par Donpi Voir le message
    Il n'y a qu'une date par IdBoutique. Si il devait y en avoir une deuxième, le record existant serait modifié pour n'en avoir qu'une.
    ...
    Mais ils sont sensé être ignoré par la pseudo jointure du cross apply.
    Je ne comprends pas bien ce que vous voulez dire...
    La requête suivante renvoie-t-elle des lignes ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT IdBoutique, DateValeure, count(*)
      FROM HistoriqueDesGenres
     GROUP BY IdBoutique, DateValeure
    having count(*) > 1
    Y a-t-il un idGenre à 0 dans la table genre ?

  9. #9
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    et que donne ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    ;WITH CTE AS(
    	SELECT 
    			GenreBoutique
    			,S.QteMin
    			,RANK() OVER (PARTITION BY S.IdBoutique ORDER BY Hin.DateValeure DESC ) Rn
    	FROM	Commande C
    	INNER JOIN StockMin S 
    		ON	S.IdArticle=C.IdArticle
    	INNER JOIN HistoriqueDesGenres Hin 
    		ON	Hin.IdBoutique = S.IdBoutique
    		AND Hin.DateValeure<= C.DateValeure
    	INNER JOIN Genre G 
    		ON	G.IdGenre=Hin.IdGenre
    )
    SELECT 
    	GenreBoutique
    	,S.QteMin
    FROM CTE
    WHERE Rn = 1
    AND C.IdCommande=123456
    (en espérant n'avoir pas fait d'erreur en "traduisant" la requête)

  10. #10
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    pourriez vous aussi indiquer l'index que vous avez créé, et qui entraine un résultat vide.

    Et par curiosité, qu'est-ce que ça donne si vous créez le même index en décroissant sur la colonne idGenre (si toute fois elle fait partie de l'index) ? (je soupçonne en effet fortement votre sous requête avec TOP)

  11. #11
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2008
    Messages
    698
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Boutique - Magasin

    Informations forums :
    Inscription : Octobre 2008
    Messages : 698
    Points : 586
    Points
    586
    Par défaut
    Bonjour,

    Alors pour ceux que ça intéresse :
    - L’accès natif de windev réinterprétè la requêtes avant de l'envoyé a sqlserver, ce qui donne un résultat différent. (a cause du top 1 justement )
    Ce, même avec la clause HSansCorrection.

    -L'index est sur HistoriqueDesGenres avec IdBoutique et DateValeur dans l'index et IdGenre dans include

    -N'ayant pas de solution j'ai écrit IdGenre dans ma table des StockMin ce qui est en soit plus juste car le genre de boutique peut changer juste après la commande ce qui donnerais un résultat biaisé.
    Après avoir copié IdGenre dans StockMin, la requêtes devient extrêmement simple et le résultat est cohérent...

    Ce qui renvoi à un truc que je dit tout le temps a mes collègues qui dit que "Si vous devez faire des requêtes complexes, vous avez probablement un problème de modélisation." (Je crois que j'ai piquer ça chez SqlPro)

    Ils arrêtent pas de me le répéter depuis hier

    Encore merci à tous.

  12. #12
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 782
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 782
    Points : 52 783
    Points
    52 783
    Billets dans le blog
    5
    Par défaut
    Le mieux est de la mettre dans une fonction table en ligne et de l'appeller dans une requête WINDEV....

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    CREATE FUNCTION F_T_DONPI (@IDcommande INT)
    RETURNS TABLE
    AS
    RETURN
    (
    SELECT DISTINCT G.GenreBoutique,S.QteMin
    FROM Commande C
    INNER JOIN StockMin S ON S.IdArticle=C.IdArticle
    CROSS apply ( 
    		SELECT top 1 IdGenre
    		FROM HistoriqueDesGenres Hin 
    		WHERE Hin.IdBoutique = S.IdBoutique
    			AND Hin.DateValeure<= C.DateValeure
    		ORDER BY Hin.DateValeure DESC
    	)  H
    INNER JOIN Genre G ON G.IdGenre=H.IdGenre
    WHERE C.IdCommande=@IDcommande)
    GO
    Dans Windev :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT *
    FROM   dbo.F_T_DONPI(123456);
    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

Discussions similaires

  1. Le M2M : science-fiction ou proche avenir de l’entreprise ?
    Par Gordon Fowler dans le forum Débats sur le développement - Le Best Of
    Réponses: 15
    Dernier message: 16/05/2013, 17h42
  2. Oracle compare les API Java à une oeuvre de science-fiction
    Par Hinault Romaric dans le forum Android
    Réponses: 23
    Dernier message: 27/02/2013, 16h59
  3. science-fiction? ==> ajout de propriétés à String
    Par javatwister dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 12/06/2010, 12h51
  4. [Science Fiction] Bolo
    Par lakitrid dans le forum Lectures
    Réponses: 0
    Dernier message: 29/10/2007, 14h31

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo