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 Procédural MySQL Discussion :

mod sur une valeur chaîne


Sujet :

SQL Procédural MySQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 527
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 527
    Par défaut mod sur une valeur chaîne
    Bonsoir

    Si je fais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT '200410100505000132202606152714' MOD 97, 200410100505000132202606152714 MOD 97;
    Résultat: 91 , 1

    Comment faire pour obtenir 1 avec le MOD sur la chaîne ?

    Merci d'avance de votre aide

  2. #2
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 877
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 877
    Par défaut
    Salut papy214.

    Le modulo s'applique sur des nombres et non sur des chaînes de caractères.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    mysql> SELECT '200410100505000132202606152714' MOD 72551;
    +--------------------------------------------+
    | '200410100505000132202606152714' MOD 72551 |
    +--------------------------------------------+
    |                                          1 |
    +--------------------------------------------+
    1 row in set (0.00 sec)
     
    mysql>
    @+

  3. #3
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 527
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 527
    Par défaut
    Bonjour Artie et condoléances pour la disparition de James

    En fait, ce problème fait suite à une traduction en MySQL d'une fonction PHP écrite par un collègue pour vérifier un iban.
    La chaîne de caractères que j'obtiens à la fin du prétraitement est celle qui correspond au nombre présent dans la requête de mon message initial.
    Je me retrouve donc en fin de code avec cette chaîne qui représente le nombre et il faut que je puisse faire ce modulo 97 pour vérifier la validité (IBAN).
    Et mon problème est que je n'arrive pas à faire considérer ma chaîne comme une valeur numérique.
    Je pensais que MySQL faisait un peu tout seul ce cast sauvage mais ça ne semble pas être le cas.

    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
     
     
    CREATE DEFINER = 'root'@'%'
    FUNCTION TestIBAN(iban VARCHAR(255))
      RETURNS bigint(20)
    BEGIN
      DECLARE t varchar(100);
      DECLARE iso varchar(100);
      DECLARE finished INTEGER DEFAULT 0;
      DECLARE ok bool;
      DECLARE a varchar(50);
      DECLARE b varchar(50);
      DECLARE pays char(2);
      DECLARE II bigint;
     
      DECLARE C CURSOR FOR
                  SELECT *  
                FROM
                  countries ;
      DECLARE CONTINUE HANDLER 
            FOR NOT FOUND SET finished = 1;
     
      IF TRIM(iban) = '' THEN
        RETURN FALSE;
      END IF;
     
      DROP TEMPORARY TABLE IF EXISTS countries;
     
      CREATE TEMPORARY TABLE countries(code varchar(3), reg varchar(255));
     
      INSERT INTO `countries`(`code`, `reg`) VALUES('AL', '[0-9]{8}[0-9A-Z]{16}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('AD', '[0-9]{8}[0-9A-Z]{12}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('AT', '[0-9]{16}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('BE', '[0-9]{12}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('BA', '[0-9]{16}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('BG', '[A-Z]{4}[0-9]{6}[0-9A-Z]{8}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('HR', '[0-9]{17}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('CY', '[0-9]{8}[0-9A-Z]{16}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('CZ', '[0-9]{20}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('DK', '[0-9]{14}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('EE', '[0-9]{16}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('FO', '[0-9]{14}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('FI', '[0-9]{14}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('FR', '[0-9]{10}[0-9A-Z]{11}[0-9]{2}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('GE', '[0-9A-Z]{2}[0-9]{16}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('DE', '[0-9]{18}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('GI', '[A-Z]{4}[0-9A-Z]{15}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('GR', '[0-9]{7}[0-9A-Z]{16}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('GL', '[0-9]{14}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('HU', '[0-9]{24}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('IS', '[0-9]{22}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('IE', '[0-9A-Z]{4}[0-9]{14}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('IL', '[0-9]{19}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('IT', '[A-Z][0-9]{10}[0-9A-Z]{12}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('KZ', '[0-9]{3}[0-9A-Z]{3}[0-9]{10}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('KW', '[A-Z]{4}[0-9]{22}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('LV', '[A-Z]{4}[0-9A-Z]{13}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('LB', '[0-9]{4}[0-9A-Z]{20}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('LI', '[0-9]{5}[0-9A-Z]{12}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('LT', '[0-9]{16}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('LU', '[0-9]{3}[0-9A-Z]{13}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('MK', '[0-9]{3}[0-9A-Z]{10}[0-9]{2}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('MT', '[A-Z]{4}[0-9]{5}[0-9A-Z]{18}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('MR', '[0-9]{23}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('MU', '[A-Z]{4}[0-9]{19}[A-Z]{3}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('MC', '[0-9]{10}[0-9A-Z]{11}[0-9]{2}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('ME', '[0-9]{18}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('NL', '[A-Z]{4}[0-9]{10}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('NO', '[0-9]{11}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('PL', '[0-9]{24}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('PT', '[0-9]{21}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('RO', '[A-Z]{4}[0-9A-Z]{16}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('SM', '[A-Z][0-9]{10}[0-9A-Z]{12}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('SA', '[0-9]{2}[0-9A-Z]{18}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('RS', '[0-9]{18}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('SK', '[0-9]{20}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('SI', '[0-9]{15}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('ES', '[0-9]{20}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('SE', '[0-9]{20}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('CH', '[0-9]{5}[0-9A-Z]{12}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('TN', '[0-9]{20}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('TR', '[0-9]{5}[0-9A-Z]{17}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('AE', '[0-9]{19}');
      INSERT INTO `countries`(`code`, `reg`) VALUES('GB', '[A-Z]{4}[0-9]{14}');
     
      SET iban = REPLACE(iban, ' ', '');
      SET pays = SUBSTRING(iban, 1, 2);
      SET t = (SELECT `reg` from countries WHERE `code` = pays);
     
      IF iban REGEXP t THEN
        SET iso = CONCAT(substr(iban, 5), substr(iban, 1, 2), substr(iban, 3, 2));
     
        -- Remplacer chaque caractère par sa valeur
        SET iso = REPLACE(iso, 'F', '15');
        SET iso = REPLACE(iso, 'R', '27');
        SET iso = REPLACE(iso, 'M', '22');
     
        SET II = iso;
        RETURN II MOD 97;
     
      END IF;  
     
      RETURN FALSE;
     
    END
    Pour vérifier si j'ai bien la chaîne attendue avant le MOD, j'ai modifié ma fonction à un moment pour renvoyer cette valeur chaîne et elle est bien conforme.
    Donc, c'est bien le 'chaine' mod 97 qui ne renvoie pas 1 alors que si c'était une valeur numérique, ça le ferait sans problème comme le montre la requête de test simple.

    Je précise là encore que c'est écrit "à l'arrache" par un utilisateur qui n'est pas un pro MySQL pour le moment.
    De plus, le code est incomplet puisqu'il manque le remplacement des autres lettres possibles, ce que je complèterai plus tard quand la fonction sera ok au moins pour les IBAN français.

    Je ne fais ça qu'épisodiquement, alors merci de ne pas trop me taper sur la tête

    Précision: J'ai fais confiance au collègue qui fait du PHP et je me suis basé sur son code.
    Peut-être qu'il y a une solution plus simple ....

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

    transtypez explicitement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT CAST('200410100505000132202606152714' AS DECIMAL(30,0)) MOD 97

  5. #5
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 527
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 527
    Par défaut
    Génial, un grand merci pour la solution.

    J'avais essayé le CAST avec un UNSIGNED et ça ne passait pas.

    Problème résolu, mais surtout, je le saurai pour la prochaine fois.

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

Discussions similaires

  1. [DEBUTANT] test sur une valeur
    Par eclipse012 dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 13/02/2007, 09h52
  2. [Serial] Commencer sur une valeur précise
    Par e1lauren dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 31/07/2006, 14h34
  3. select sur une liste chaînée
    Par wtfu dans le forum Langage SQL
    Réponses: 1
    Dernier message: 01/06/2006, 15h30
  4. Trier sur une valeur de champs et non sur le nom du champs
    Par kamalkam dans le forum Langage SQL
    Réponses: 1
    Dernier message: 09/05/2006, 17h41
  5. [XSL]appliquer la fonction substring sur une valeur récupéré
    Par totoranky dans le forum XSL/XSLT/XPATH
    Réponses: 7
    Dernier message: 22/02/2006, 17h21

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