Traitée ORDER sans effet dans les vue

  • samedi 5 mai 2012 17:56
     
      A du code

    Bonjour,

    une select sur la vue suivante ne trie pas les enregistrements : SELECT * FROM [V_Trt_Traitement_Propriete]

    Le order est dans la vue :

    CREATE VIEW [dbo].[V_Trt_Traitement_Propriete]
    AS
    SELECT TOP (100) PERCENT WITH TIES Code, idTraitements_Propriete, idTraitements_Plan, Nom, Description, Valeur, ASPType
    FROM     (SELECT TOP (100) PERCENT dbo.AS_Traitements.Code, dbo.AS_Traitements_Propriete.idTraitements_Propriete, dbo.AS_Traitements_Propriete.idTraitements_Plan, 
                                        dbo.AS_Traitements_Propriete.Nom, dbo.AS_Traitements_Propriete.Description, dbo.AS_Traitements_Propriete.Valeur, 
                                        dbo.AS_Traitements_Propriete.ASPType
                      FROM      dbo.AS_Traitements INNER JOIN
                                        dbo.AS_Traitements_Plan ON dbo.AS_Traitements.idTraitement = dbo.AS_Traitements_Plan.idTraitement INNER JOIN
                                        dbo.AS_Traitements_Propriete ON dbo.AS_Traitements_Plan.idTraitements_Plan = dbo.AS_Traitements_Propriete.idTraitements_Plan) AS derivedtbl_1
    ORDER BY Code, Nom

    FB

Toutes les réponses

  • samedi 5 mai 2012 18:32
     
     

    A priori j'ai cru voir sur le net que c'est un problème connu

    il ne faut pas faire d'order by dans les vue (couillon ça...)


    FB

  • samedi 5 mai 2012 19:07
     
     

    Bonjour,

    C'est effectivement un changement de comportement effectif depuis la version 2005. Etant donné que ORDER BY était explicitement interdit dans les vues je pense que c'est ce genre d'infâme bidouille qu'il était un peu couillon d'utiliser ;-)

    J'ai d'ailleurs hérité d'une application faite comme cela et en plus les vues s'appuient les unes sur les autres avec un niveau de profondeur excessif à mon goût :-(


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".



  • samedi 5 mai 2012 19:59
     
     

    Ce n'est pas un problème de comportement hélas.

    Ce phénomène ne répond pas au fondement même d'une base de données... Une vue doit avoir le même comportement que tout ordre SQL équivalent.

    J'espère que Microsoft va remédier un jour à cette anomalie, ça fait pas sérieux du tout.


    FB


  • dimanche 6 mai 2012 08:34
     
     

    Ce changement est documenté explicitement dans la doc de SQL Server 2005 et argumenté par l'équipe SQL Server par exemple ici : http://blogs.msdn.com/b/queryoptteam/archive/2006/03/24/560396.aspx. L'auteur semblant regretter plutôt la confusion introduite par le ORDER BY du TOP, je parierais plutôt un jour sur l'alignement de la syntaxe du TOP avec le ROW_NUMBER même si cela a sans doute une très faible priorité.

    En résumé, ma compréhension est que TOP ORDER BY est en réalité une instruction de *sélection* et non pas de tri. La présence du ORDER BY a pour but de pouvoir indiquer à TOP l'ordre des lignes pour pouvoir identifier les x % premières lignes qui doivent être sélectionnées. Le tri obtenu au final n'est qu'un sous-produit de la méthode utilisée pour la sélection. Ici, TOP 100 PERCENT ORDER BY demande simplement une sélection de toutes les lignes et l'optimiseur produit maintenant un simple SELECT car le tri n'est pas nécessaire pour sélectionner les lignes concernées.

    C'est probablement fait également pour une requête toute simple mais ici on va justement faire directement un ORDER BY seul plutôt que l'astuce du TOP 100 PERCENT ORDER BY dans une vue et donc cela passe sans doute beaucoup plus inaperçu. Après test : le comportement est effectivement différent. J'imagine que dans ce cas la présence du ORDER BY dans le résultat final est considéré également comme une "vraie" demande de tri ce qui explique pourquoi l'auteur évoquait également le SELECT sur des sous-requêtes dans l'article...

    Accessoirement, l'article indique d'ailleurs également que refaire un SELECT sur un résultat précédent trié ne garantie pas que le résultat soit toujours trié (même si concrètement cela sera sans doute toujours le cas). Je pense que c'est probablement pour cela que le ORDER BY est explicitement interdit dans une vue.

    De même que pour TOP x PERCENT ORDER BY (je reconnais que je pousse le bouchon un peu loin), DISTINCT ou ROW_NUMBER() OVER (ORDER BY) demandent respectivement un dédoublonnage ou une numérotation et le tri final obtenu n'est également qu'un sous-produit de la méthode utilisée pour satisfaire cette demande (et on peut d'ailleurs inclure une "vraie" clause ORDER BY en plus).

    Au final, on retombe sur la bonne vieille règle fondamentale qui est que la seule façon d'avoir la *garantie* d'un résultat trié est d'utiliser explicitement une clause ORDER BY sur le résultat final.


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".



  • dimanche 6 mai 2012 08:45
     
     

    Quelques soient les arguments, le résultat est le même.

    Microsoft ne respecte pas les fondements du language SQL et des bases de données.

    Et ceci, il va finir par le payer. Je travaille depuis 95 dans les environnements Microsoft (et ORACLE).

    On a déjà beaucoup de concurrence avec le monde opensource.

    Mais en ne respectant pas ce type de règle, ceci pérénise le fait que SQL SERVER restera en dessous de ses concurrents.

    C'est un choix, mais si ça continue, je finirais par ne plus le préconiser à mes clients...


    FB

  • dimanche 6 mai 2012 09:00
     
     
    Question de point de vue. Pour moi c'est une instruction de sélection, pas de tri. Je crois d'ailleurs que TOP n'est pas dans le standard SQL. Par curiosité, est-il possible de retourner des lignes triées depuis une vue Oracle ?

    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".

  • dimanche 6 mai 2012 09:49
     
      A du code

    Ben non ceci n'est pas un point de vue, mais un fait. Un SGBD doit permettre de manipuler les données le plus loin possible. Un language SQL a été mis en place depuis longtemps. Le problème du TOP avec un ORDER BY montre bien que Microsoft n'aborde pas le problème comme il faut.

    ORDER BY est par définition un TRI et en aucun cas un filtre!!!

    ORDER BY se traduit pas TRIER PAR

    Oui biensur ORACLE le permet. La vue suivante fonctionne et effectue bien un tri descendant sur la date  :

    CREATE OR REPLACE FORCE VIEW INFOC.VCR_FBT_Test
    (
       DATEFACT,
       CODART,
       COLLECTION,
       CODE_PAYS,
       CA,
       TYPECA
    )
    AS
    SELECT * FROM (
       SELECT ca.DATEFACT,
              ca.GR_FAM,
              ca.LIBELLE,
              ca.CODE_PAYS,
              ca.PVNETQ ca,
              'CA_REEL' AS typeca
         FROM VCR_CA ca
        WHERE CA.DATEFACT BETWEEN '01/01/2009' AND '31/12/2009'
              AND ca.CODE_PAYS = 'D'
       UNION ALL
       (SELECT infoc.gr_budget_ca.date_fact datefact,
               infoc.gr_budget_ca.codartfam codart,
               infoc.gr_budget_ca.fam libelle,
               infoc.gr_budget_ca.code_pays,
               --infoc.gr_budget_ca.lib_pays,
               infoc.gr_budget_ca.ca,
               infoc.gr_budget_ca.typeca
          FROM infoc.gr_budget_ca ))
          ORDER BY DATEFACT DESC


    FB



  • dimanche 6 mai 2012 09:55
     
     

    Je rappelle qu'en THEORIE une vue doit :

    => Pouvoir accepter n'importe qu'elle ordre SELECT sans limitation

    => Avoir le même comportement que l'ordre SELECT en dehors de la vue

    Ceci est un principe de base et Microsoft ne le respecte pas (ou plus). Ce phénomène pourrait même s'apparenter à une régression.


    FB

  • dimanche 6 mai 2012 16:27
     
     

    Mon premier contact avec SQL date un peu et il fort possible que j'ai loupé des évolutions mais pour moi, une vue est censée se comporter comme une table et donc seule une clause ORDER BY explicite à la sélection des données de la vue peut garantir l'ordre de tri (accessoirement je me souviens d'ailleur qu'à l'époque, les jointures étaient faites avec des égalités ce qui occasionnait parfois des comportements différents d'une base à l'autre même pour une jointure !).

    Apparemment ce point de vue m'a été profitable SQL Server ne supportant donc pas de toute façon le tri dans les vues.

    J'imagine que cela ne sera pas applicable à votre cas mais pour ce qui est de l'appli dont je parlais j'ai trouvé : http://visakhm.blogspot.fr/2010/01/behaviour-of-order-by-inside-view.html. Il y a un patch qui devrait permettre de réactiver ce comportement en passant la base en mode compatibilité 80. Cela devrait me permettre de la migrer depuis son SQL Server 2000 actuel en attendant de remplacer les TOP 100 PERCENT ORDER BY par un simple ORDER BY ce qui est et restera ma préférence personnelle.


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".



  • dimanche 6 mai 2012 17:00
     
     Traitée

    Oui j'avais vu ce cas, mais comme vous disiez plus haut, je ne suis pas du style à faire des verrues. Si je vois qu'une solution n'est plus viable, je m'en passe.

    Non, une vue n'a pas le comportement d'une table (sauf peut être dans le cas d'ORACLE ou il est possible de dématérialiser des vues mais SQL Server en est TRES TRES LOIN).

    Le scénario d'interprétation d'une chaine SQL est le suivant :
    Une chaine SQL quelle qu'elle soit est envoyée à une base, le noyau procède tout d'abord analyse syntaxique.
    Puis, il va l'analyser grace à son dictionnaire de données (tables systèmes spécifiques à chaque SGBD permettant d'explorer tous les objets d'une base et leur propriétés) les tables, les jointures et il va rechercher l'algorithme le plus adapter pour l'exécution de la requete.

    Quel est l'intéret d'une vue?
    Eviter de stocker des requetes complexes côté IHM
    Optimiser un tout petit peu l'exécution de la requête (analyse syntaxique par exemple est déjà faite)

    J'ai beaucoup pratiqué le language SQL (DB2, Oracle, SQL Server et ACCESS...), je n'ai jamais eu le problème que vous avez soulevé (problème de jointure).

    Bon on s'étale^^

    Mais ceci pour conclure que Microsoft a intéret à régler ce type de problème sinon leur base risque fort d'être rattrapée par des SGBD opensource (si c'est pas déjà fait).


    FB

  • dimanche 6 mai 2012 20:33
     
      A du code

    De mon côté je n'aurais sans doute jamais ce souci. Je fais bien sûr des vues lorsque nécessaire mais je n'ai jamais éprouvé le besoin d'y inclure l'ordre de tri (peut-être parce que ce n'était déjà pas possible à l'époque ?). De même que je ne considère pas qu'une table est triée, je fais donc toujours un SELECT ORDER BY qu'il s'agisse d'une vue ou d'une table. L'IHM en plus peut justement vouloir piloter l'ordre, faire de la pagination etc..., donc il me semble plus naturel de laisser l'ordre en dehors de la vue, de même je ne vois pas ce que va donner une jointure entre deux vues triées, dans quel ordre les lignes vont être présentées ? J'imagine que l'on perd l'ordre et que l'ordre devient celui jugé le plus pratique pour faire la jointure ?, donc je vais sans doute trier à nouveau explicitement donc au final inutile d'inclure l'ordre dans les vues.

    Ah éventuellement voir peut-être qq chose comme :

    CREATE VIEW v AS 
    SELECT Name,PersonId,ROW_NUMBER() OVER (ORDER BY Name,PersonId) AS _ForceOrder
    FROM People

    ROW_NUMBER calcule la numérotation et semble donc forcer l'ordre de tri quand je fais derrière un select * from v.

    Autre idée. Je viens de tester également :

    CREATE VIEW v AS 
    SELECT TOP 2147483647 *
    FROM People
    ORDER BY Name

    Et cela marche également. Cette dernière solution semble donc la plus simple en remplacement du TOP 100 PERCENT.

    Eventuellement voir http://connect.microsoft.com/  et l'idéal serait alors que SQL Server ajoute explicitement le support du ORDER BY classique dans une vue - vous pourrez l'utiliser, je pourrais continuer à trier en dehors des vues et tout le monde sera content ;-)

    Merci de cette confrontation ferme mais néanmoins courtoise...


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".


  • lundi 7 mai 2012 08:46
     
     
    Un petit support pour Patrice !
    order by ne fait pas partie du standard ANSI pour le create view.
    La définition que je connais d'une vue est celle d'un ensemble de lignes
    semblable à une table virtuelle, donc non trié.
    Pour ma part, je pratique le sql depuis trop peu de temps pour avoir
    basé beaucoup d'interfaces de présentation sur cette fonctionnalité de
    ms sql qui n'aurait jamais dû être (à mon sens).
    Juste pour s'amuser, il faudrait poster cela sur le groupe US et voir ce
    qu'en pensent les cadors !
     
     

    Fred