Comparaison de Varchar(20)

Résolu
Bonjour,

j'ai une requête SQL qui me retourne cette erreur:

The conversion of the varchar value '78532973952750862890' overflowed an int column. Maximum integer value exceeded.

J'ai cru comprendre que SQL convertissait ce varchar en Int pour la comparaison et que le problème venait de là?
Y'a-t-il une solution pour éviter ce genre de problème?



--
La culture c'est comme la confiture, moins en a plus on l'étale!

12 réponses

Résumé de la discussion

Problème récurrent : une erreur SQL survient lors de la conversion d'une valeur varchar en int, provoquant un dépassement lorsque le champ NUCDE reçoit une valeur numérique dépassant le maximum d'un int. Des réponses proposent d'éviter l'inférence du type en utilisant BigInt ou bigint dans les paramètres et de forcer le type dès le départ pour les comparaisons et les filtres. D'autres évoquent des problèmes autour des guillemets simples dans les requêtes dynamiques et suggèrent d'échapper correctement les caractères, de vérifier LIKE vs égalité, et d'ajuster l'assemblage de la requête. En pratique, le recours à une colonne ou paramètre de type bigint ou numeric est préconisé pour éviter l'erreur et garantir une comparaison fiable même avec des valeurs numériques longues.

Bobot (l’IA à votre service)
  1. Salut,

    Peut tu nous donner ta requête ??
    0
    1. En l'occurence c'est une procédure stockée qui génére une requête SQL dynamiquement, la voilà en simplifié:

      
      @psnum_cde          varchar(20)
      BEGIN
      set @strSQL = 'SELECT * FROM EDFTENT WHERE CDTYPMSGEDI = ''INVOIC''' 
      
      BEGIN 
                 
                 set @strSQL = @strSQL + ' AND NUCDE = '''+@psnum_cde+''''
                 
             END
      
      set @strSQL = @strSQL + 'ORDER BY DTFAC DESC'
         
         EXEC sp_executeSQL  @strSQL
      
      END
      


      J'ai essayé de forcer une conversion en BIGINT mais j'obtiens toujours la même chose...
      0
      1. Et du coup NUCDE c'est pas un varchar ?? Essaye plutôt de convertir celui-là en varchar et de faire la comparaison avec un LIKE.
        0
        1. Ben si...
          Ma colonne NUCDE est bien de type VARCHAR(20) dans ma base!
          Mais apparement pour comparer les VARCHAR il passe par des INT...
          Je vais essayer de faire un LIKE pour voir

          La culture c'est comme la confiture, moins en a plus on l'étale!
          0
          1. Marche pas avec le LIKE!
            Je vais essayer de déclarer le paramètre en tant que BigInt dès le début de la Proc!
            0
        2. C'est très bizarre. Et tu as essayé d'exécuter ta requêtes avec de vraies valeurs sans passer par ta procédure ??
          Comme ça :

          SELECT * FROM EDFTENT WHERE CDTYPMSGEDI = 'INVOIC'  AND NUCDE = 1 ;
          0
          1. Si je lance la requête:

            SELECT * FROM EDFTENT WHERE CDTYPMSGEDI = 'INVOIC' AND NUCDE = '78532973952750862890'

            Par SQL Server Manager, ca marche très bien!

            Par contre dès que je passe par ma proc stock, l'erreur apparait...

            Peut être qu'en modifiant le type de la colonne dans la base en BigInt ca passerait, sauf que j'ai pas la main sur la base...
            Donc pas possible de tester :S
            0
            1. Non pas la peine de modifier le type vue que ça passe quand on entre direct la requête. Le problème est sur ta procédure. Je dirai un problème de guillemets. C'est pour ça qu'il pense que tu compares avec un chiffre alors que c'est une chaine.
              Ya pas moyen d'afficher la requête générée pour voir si elle est correcte ?
              0
              1. Je peux faire un print a la place du execute, mais je sais pas ou ca le print ^^
                0
            2. C'est bien facheux ^^
              N'y connaissant pas grand chose, je te propose un petit dbms ouput :

               DBMS OUTPUT.PUT LINE(@strSQL)


              sans grande conviction
              0
              1. Apparement j'ai pas accès à DBSM.
                Car il n'est pas reconnu!
                0
              2. C'est DBMS et pas DBSM.

                Je pense que ton problème vient du fait que tu utilises plusieurs guilletmets à la suite et qui ne veulent pas dire la même chose. A mon avis il faut utiliser un caractère d'échappement. Je vais faire une petite recherche et je reviens.
                0
            3. A priori la syntaxe obtenu est celle-ci:

              SELECT * FROM EDFTENT WHERE CDTYPMSGEDI = 'INVOIC' AND NUCDE = '78532973952750862890'

              Si je me fie aux couleur dans l'editeur SQL!
              0
              1. Donc apparament pour échapper un caractère c'est anti-slash qu'il faut utiliser. Essaye donc ceci :

                @psnum_cde          varchar(20)
                BEGIN
                set @strSQL = 'SELECT * FROM EDFTENT WHERE CDTYPMSGEDI = \'INVOIC\'' 
                
                BEGIN 
                           
                           set @strSQL = @strSQL + ' AND NUCDE = \''+@psnum_cde+'\''
                           
                       END
                
                set @strSQL = @strSQL + 'ORDER BY DTFAC DESC'
                   
                   EXEC sp_executeSQL  @strSQL
                
                END


                Dis moi...
                0
                1. J'avais déjà essayer d'échapper un caractère de la sorte, puisque ca se fait comme ca d'habitude!
                  Mais ca marchais pas et en fait c'est avec un ' qu'on échappe un caractère apparement!

                  Par exemple cette ligne fonctionne très bien dans la proc stock:

                  set @strSQL = @strSQL + ' AND DTFAC LIKE ''%'+@psannee+'%'''
                  0
                2. En effet les \ ne fonctionne pas pour échapper un caractère j'ai re testé!
                  0
                3. Et non justement. Le caractère ' sert à définir ce qui est textuel de ce qui ne l'est pas. C'est normal que cette ligne fonctionne. Mais dans ton cas, l'analyseur ne sait pas faire la différence entre les ' qui séparent les parties textes des autres parties et les ' qui font parti de la requête que tu génère.
                  Je viens de voir que pour échapper un ' il faut le doubler. Donc ça donne :

                  @psnum_cde          varchar(20)
                  BEGIN
                  set @strSQL = 'SELECT * FROM EDFTENT WHERE CDTYPMSGEDI = ''INVOIC''' 
                  
                  BEGIN 
                             
                             set @strSQL = @strSQL + ' AND NUCDE = '''+@psnum_cde+''''
                             
                         END
                  
                  set @strSQL = @strSQL + 'ORDER BY DTFAC DESC'
                     
                     EXEC sp_executeSQL  @strSQL
                  
                  END


                  Il n'y a qu'une seule chose qui change c'est qu'il y a 3 ' devant INVOIC. Essaye ça et dis moi.
                  Si ce n'est pas ça je t'avoue que je ne sais plus trop quoi faire...
                  0
                4. ca marche pas!
                  Apparement ca ne serait pas un problème de syntaxe...
                  Mais alors par contre je vois pas d'ou ca vient :S
                  0
                5. peut-être sur la concaténation.
                  Essaye d'utiliser le double | à la place du + :

                  psnum_cde          varchar(20)
                  BEGIN
                  set @strSQL = 'SELECT * FROM EDFTENT WHERE CDTYPMSGEDI = ''INVOIC''' 
                  
                  BEGIN 
                             
                             set @strSQL = @strSQL || ' AND NUCDE = ''' || @psnum_cde || ''''
                             
                         END
                  
                  set @strSQL = @strSQL || 'ORDER BY DTFAC DESC'
                     
                     EXEC sp_executeSQL  @strSQL
                  
                  END


                  Mais essaye d'afficher les résultats du print pour qu'on voit à quoi elles ressemblent les requêtes.
                  0
              2. J'ai trouvé...
                Et en fait tu ne pouvais pas trouvé j'avais loupé mon copier-coller en haut et il manquait le if!
                Et c'était la dedans que tout ce jouer:

                j'avais mis if @psnum_cde != 0

                Du c'est à cet endroit qu'il convertissait en int...

                Merci de ton aide!
                0
                1. Ah ben c'est malin ça ^^
                  En tout cas contant que ça fonctionne !!!
                  0
                  1. Evidement il a fallu que la personne que j'avais appelé pour m'aider soit à côté de moi pour que je vois l'erreur!
                    0
                  2. Normal, c'est toujours comme ça !!!
                    0