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 :

RegEx dans le where


Sujet :

MS SQL Server

  1. #1
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 243
    Par défaut RegEx dans le where
    Salut à tous, j'ai un petit soucis avec un filtre where.

    Le contexte :
    Je fais une reprise de données sur une vieille appli dont les bases sont sous SQLServer.
    Dans la nouvelle structure, j'ai un champ d'une table qui ne peut contenir que des caractères autorisés à savoir Alphanumérique sans accent, les /-%+$. et l'espace.
    Certaines données actuelles contiennent des caractères donc interdits.

    Je veux faire une requête pour sortir les enregistrements dont le champs contient ces caractères interdits, pour pouvoir mettre quelqu'un dessus ensuite pour corriger ces données afin de ne pas bloquer la récupération (il est probable qu'il ne soit pas possible de faire une correction aveugle par une fonction Replace).

    N'ayant pas envie de me taper une série de Like dans le Where, je me dis qu'une RegEx doit être capable de faire ça.
    Donc récupérer, les enregistrements dont le champs contient un ou plusieurs caractères autres que ceux autorisés.

    Il faudrait apparemment que j'utilise une fonction xp_regex_format, c'est bien ça ?

    Par contre, je suis bien incapable d'écrire la RegEx elle-même. Un peu d'aide ?

    PS : base de prod sous SQLServer2000
    Possibilité de travailler sur une copie de test sous SQLServer 208 Express, si besoin.

  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
    Par défaut
    Bonjour


    Vous devriez pouvoir vous en sortir avec un simple LIKE, en utilisant la bonne collation.

    Pouvez vous nous fournir un jeu d'essai, avec 5 ou 6 valeurs valides, et 5 ou 6 valeurs invalides (+ raison de l'invalidité)

  3. #3
    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
    Par défaut
    Citation Envoyé par sevyc64 Voir le message
    Dans la nouvelle structure, j'ai un champ d'une table qui ne peut contenir que des caractères autorisés à savoir Alphanumérique sans accent, les /-%+$. et l'espace.
    Y a-t-il une contrainte sur cette colonne ?


    que donne cette requête (elle devrait vous sortir les valeurs invalides) :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT LaColonne
    FROM LaTableSource
    WHERE t COLLATE Latin1_General_BIN LIKE  '%[^0-9A-Za-z/-%+$. ]%'

  4. #4
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 243
    Par défaut
    Ok, apparemment on a pas besoin de fonctions particulières pour utiliser une RegEx dans avec LIKE. Déjà, j'ai appris ça.

    Pour la contrainte sur la base, sur la base source, il n'y en a pas, sinon ça n'aurait pas pu être saisi. Pour la base de destination, je ne sais pas, je n'y ai pas accès. C'est une base propriétaire, l'import se fait par l'application propriétaire (SAGE L100) via fichiers textes (que je dois générer moi) et c'est l'application qui indique elle-même les erreurs.

    Ensuite ta regex n'est pas bonne. Elle me renvoie des champs qui sont corrects. par exemple, elle me renvoie ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    171-5231              bon
    AC-162BYILY70H-AR     bon
    153-1116-ND           bon
    BE113-E Prestation    bon
    WG160128BTFHTZ/#      pas bon, #
    modèle A              pas bon, accent
    modèle C              pas bon, accent
    à compléter           pas bon, 2 accents
    100815,0006           pas bon, virgule
    PD10/8211-0,5         pas bon, virgule
    N°1092C               pas bon, °
    08 04 374 (41-50)     pas bon, parenthèses
    J'ai extrait ces valeurs à la main, ce n'est qu'un échantillon de ce que je peux avoir, la liste n'est pas exhaustive.

  5. #5
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 243
    Par défaut
    Pour un premier passage de fichier, j'ai repéré les caractères suivants qui ne seraient pas bons :
    # è é à , ( ) = * " °
    Pour l'instant, pour mes essais, je fais des remplacements à l'arrache mais au final il faudra analyser chaque cas pour savoir quoi remplacer ou comment codifier autrement.

  6. #6
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 990
    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 990
    Billets dans le blog
    6
    Par défaut
    REGEX est non seulement contre performant, mais sujet à des attaques de DOS.

    Voici une solution avec like :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CREATE TABLE T (C VARCHAR(256))
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    INSERT INTO T VALUES 
    ('171-5231'), 
    ('AC-162BYILY70H-AR'),
    ('153-1116-ND'),
    ('BE113-E Prestation'), 
    ('WG160128BTFHTZ/#'), 
    ('modèle A'), 
    ('modèle C'), 
    ('à compléter'),
    ('100815,0006'),
    ('PD10/8211-0,5'),
    ('N°1092C'),
    ('08 04 374 (41-50)');
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT *
    FROM T 
    WHERE C COLLATE French_CI_AS LIKE REPLICATE('[ abcdefghijklmnopqrstuvwxyz0123456789/~-%+$.]', LEN(C)) ESCAPE '~'
    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/ * * * * *

  7. #7
    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
    Par défaut
    oui, en effet, je n'ai pas fait attention au "-" dans la liste des caractères spéciaux acceptés. le tiret sert a définir des plages, il faut donc le déspécialiser dans la requête que j'ai donnée :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT LaColonne
    FROM LaTableSource
    WHERE t COLLATE Latin1_General_BIN LIKE  '%[^0-9A-Za-z/|-%+$. ]%'  ESCAPE '|'

  8. #8
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 243
    Par défaut
    aieeeuuuuu >
    Ta requête corrigée semble me renvoyer effectivement que des enregistrements qui ont un caractère pas bon. (j'ai pas tout analyser dans le détail)

    SQLpro >
    Ta requête semble faire l'inverse (des résultats que j'ai, et de ce que j'en comprend), elle ne renvoie que les enregistrements qui sont bons. Hors moi, c'est ceux qui sont mauvais qu'il me faut.

    Problème :
    J'ai un total de 8067 lignes dans la table
    la requête de aieeeuuuuu me renvoie 61 lignes
    la requête de SQLpro me renvoie 7172 lignes, laissant supposer 895 lignes incorrectes.

    Il faut donc que je recherche ce qui fait cet écart entre 61 et 895 !

  9. #9
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 990
    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 990
    Billets dans le blog
    6
    Par défaut
    NOT LIKE !

    Faudrait quand même investir un peu de jus de cerveau pour apprendre le minimum en matière de SQL !!!!!

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

  10. #10
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 243
    Par défaut


    Bien sur que j'avais tenté NOT LIKE, sauf que ça me renvoie 157 lignes, d’où investigations.

    Pour les lignes manquantes, c'est à dire 738, c'est tout simplement que le champs en question est à Null, ce qui est pas mal, pour une référence censée être obligatoire.

    De plus ça me permet de m’apercevoir, que ce champs a été renseigné n'importe comment. Ce qui est censé contenir une référence, contient parfois un commentaire, une adresse mail, ou autres bizarreries.

  11. #11
    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
    Par défaut
    Citation Envoyé par sevyc64 Voir le message
    la requête de SQLpro me renvoie 7172 lignes, laissant supposer 895 lignes incorrectes.
    Non, les valeur qui ne sont pas incorrectes, ne sont pas forcément correctes !
    Vous devez avoir des NULL

    Il faut donc que je recherche ce qui fait cet écart entre 61 et 895 !

  12. #12
    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
    Par défaut
    notez également la légère différence entre le Pattern de SQLPro et le mien :
    Mon pattern considérera 3 caractères invalides que le pattern de SQLPro considérera comme valides :
    ¹
    ²
    ³

    (exposant 1, 2 et 3)

    C'est très mineur, et à part cela, je ne vois pas de différence sémantique.

  13. #13
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 243
    Par défaut
    Oui aieeeuuuuu, ton pattern considère les accents comme valide, mais ils sont invalides, d’où la différence entre 61 lignes invalide avec ton pattern et 157 avec celui de SQLPro

  14. #14
    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
    Par défaut
    Citation Envoyé par sevyc64 Voir le message
    Oui aieeeuuuuu, ton pattern considère les accents comme valide

    Non ! vous avez du oublier de préciser la collation : COLLATE Latin1_General_BINCombien avez vous de lignes à NULL pour cette colonne ?

  15. #15
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 990
    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 990
    Billets dans le blog
    6
    Par défaut
    Ma requête est d'ailleurs erronée. Voici une correction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT *
    FROM T 
    WHERE C COLLATE French_CI_AS LIKE REPLICATE('[ abcdefghijklmnopqrstuvwxyz0123456789/~-~%+$.]', LEN(C)) ESCAPE '~'
    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/ * * * * *

  16. #16
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 243
    Par défaut
    Citation Envoyé par aieeeuuuuu Voir le message
    Non ! vous avez du oublier de préciser la collation : COLLATE Latin1_General_BINCombien avez vous de lignes à NULL pour cette colonne ?
    Tu as raison !

    mauvais copier/coller (comme toujours) le COLLATE avait sauté

    Les 2 requêtes renvoient bien le même résultat, 157 lignes à reprendre.
    (en réalité c'est presque toute la base qu'il faudrait reprendre, mais ça c'est pas mon boulot)

    SQLpro> ta correction ne change rien dans ce cas particulier mais aurait pu effectivement.

    Merci, à vous 2

  17. #17
    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
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    Ma requête est d'ailleurs erronée. Voici une correction :
    Non, je pense qu'elle était bonne, le "%" étant entre crochets [] et donc déjà déspécialisé...

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

Discussions similaires

  1. [RegEx] supprimer <a href...</a> par regex dans pages html.
    Par moldak dans le forum Langage
    Réponses: 10
    Dernier message: 15/11/2012, 16h02
  2. Réponses: 9
    Dernier message: 05/07/2005, 08h37
  3. INNER JOIN ... ON ... ou jointure dans clause where
    Par schmur1 dans le forum MS SQL Server
    Réponses: 12
    Dernier message: 28/06/2005, 09h16
  4. Plusieurs clauses OR dans le WHERE
    Par NeHuS dans le forum Langage SQL
    Réponses: 3
    Dernier message: 28/01/2005, 16h19
  5. 2 champs dans un where , possible en sql server ?
    Par voyageur dans le forum MS SQL Server
    Réponses: 10
    Dernier message: 19/10/2004, 05h01

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