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

SQL Oracle Discussion :

[11g] Classement et filtres sur des varchars alphanumériques


Sujet :

SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Août 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Transports

    Informations forums :
    Inscription : Août 2012
    Messages : 8
    Par défaut [11g] Classement et filtres sur des varchars alphanumériques
    Bonjour,


    Je suis en présence d'un comportement surprenant lié au classement de données de type varchar2 : order by et les clauses de filtre ne semblent pas classer de la même manière.

    Un exemple valant généralement mieux qu'un long discours, voici les requêtes dont les résultats me semblent peu cohérents :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    select numero_dossier from plop order by numero_dossier;
     
    select numero_dossier from plop where numero_dossier > 'MOA01' order by numero_dossier;
    select numero_dossier from plop where numero_dossier between 'MOA01' and '26082' order by numero_dossier;
     
    select numero_dossier from plop where numero_dossier between '26082' and 'MOA01' order by numero_dossier;
     
    select numero_dossier from plop where numero_dossier between '105340' and '26082' order by numero_dossier;

    La première requête me fournit un certain nombre de résultats, ordonnés de la façon suivante :
    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
     
    MOA01
    105340
    105340
    105340
    105340
    17470
    22940/41
    26080
    26081
    26082
    26083
    26084
    26085
    26087
    26089
    2706
    2706
    2706
     
    etc...
    Les requêtes 2 et 3 ne fournissent AUCUN résultat (alors que 'MOA01' semble être considéré comme la valeur la plus petite de ma donnée numero_dossier)

    La requête 4 renvoie toutes les données possibles sauf
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    105340
    105340
    105340
    105340
    17470
    22940/41
    26080
    26081
    que la clause order by présente bien comme comprises entre mes deux valeurs.

    La 5e et dernière requête renvoie, quant à elle, un résultat cohérent avec l'ordre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    105340
    105340
    105340
    105340
    17470
    22940/41
    26080
    26081
    26082



    Quelqu'un aurait-il des explications à m'apporter par rapport à cette problématique ? des pistes de solution (sans remettre en cause la structure des données) ?

    D'avance merci.

  2. #2
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2014
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juillet 2014
    Messages : 37
    Par défaut
    Bonjour,

    si vous jouez cette requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT *
    FROM nls_session_parameters
    WHERE parameter IN ('NLS_COMP', 'NLS_SORT');
    Obtenez vous comme résultat BINARY pour NLS_COMP et un nom de langue (sur ma base de test FRENCH) pour NLS_SORT. Ce qui veut dire que pour les comparaison, la base passe par les valeurs binaires des valeurs et pour les tris elle passe par un ordre alhpabetique.

    Pour votre problème, essayez de passer en mode lunguistique pour les comparaisons :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    alter session set nls_comp=LINGUISTIC;

  3. #3
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    22 002
    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 : 22 002
    Billets dans le blog
    6
    Par défaut
    Oracle contrairement à ses concurrent refuse d'intégrer les collations de la norme SQL, qui permettent de régler élégamment ce genre de problématiques, mais utilise l'imbitable NLS (global à la session) pour tenter d'apporter une solution.
    Jouez avec le NLS en l'indiquant au niveau de la session ou dans votre requête :
    http://ss64.com/ora/syntax-nls.html

    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/ * * * * *

  4. #4
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Août 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Transports

    Informations forums :
    Inscription : Août 2012
    Messages : 8
    Par défaut
    Merci à tous les deux.


    Effectivement, une modification du nls_comp rend les résultats plus cohérents.
    Ne me reste plus qu'à trouver comment modifier ce paramètre pour une requête spécifiquement via Hibernate (ce serait trop facile si c'était pour taper directement une base )

  5. #5
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Comme 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
    22
    23
    24
    With plop (numero_dossier) as
    (
    select cast(column_value as varchar2(10))
      from table(sys.odcivarchar2list('MOA01', '105340', '105340', '105340',
           '105340', '17470', '22940/41', '26080', '26081', '26082', '26083',
           '26084', '26085', '26087', '26089', '2706', '2706', '2706'))
    )
      select numero_dossier
        from plop
       where NLSSORT(numero_dossier, 'NLS_SORT=French') between NLSSORT('MOA01', 'NLS_SORT=French') and NLSSORT('26082', 'NLS_SORT=French')
    order by numero_dossier asc;
     
    NUMERO_DOSSIER
    --------------
    MOA01
    105340
    105340
    105340
    105340
    17470
    22940/41
    26080
    26081
    26082
    Mais je suis d'accord avec SQLPro, ce serait beaucoup plus simple d'écrire, comme sous les autres SGBD :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      select numero_dossier
        from plop
       where numero_dossier between 'MOA01' and '26082' collate 'French'
    order by numero_dossier asc;

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 09/09/2008, 14h12
  2. [RegEx] Expression régulière sur des caractères alphanumériques
    Par hash95 dans le forum Langage
    Réponses: 3
    Dernier message: 16/01/2008, 17h26
  3. Filtre sur des invites
    Par yalla3 dans le forum Deski
    Réponses: 6
    Dernier message: 16/08/2007, 20h19
  4. Problème de casse sur des varchar
    Par PomPom dans le forum Requêtes
    Réponses: 2
    Dernier message: 20/09/2006, 18h28
  5. Requête filtre sur des rendez vous
    Par jdotti dans le forum Outils
    Réponses: 5
    Dernier message: 17/03/2006, 15h41

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