
{"id":1273,"date":"2012-06-13T10:33:30","date_gmt":"2012-06-13T09:33:30","guid":{"rendered":"http:\/\/dasini.net\/blog\/?p=1273"},"modified":"2012-06-19T09:22:31","modified_gmt":"2012-06-19T08:22:31","slug":"error-1690-22003-bigint-unsigned-value-is-out-of-range","status":"publish","type":"post","link":"https:\/\/dasini.net\/blog\/2012\/06\/13\/error-1690-22003-bigint-unsigned-value-is-out-of-range\/","title":{"rendered":"ERROR 1690 (22003): BIGINT UNSIGNED value is out of range"},"content":{"rendered":"<p>Le probl\u00e8me du jour, une table qui contient (entre autre) 2 colonnes de type entier non sign\u00e9 ( NombPart &amp; NombInscr).<\/p>\n<p>&nbsp;<\/p>\n<address>CREATE TABLE VoteInfo (<\/address>\n<address>NombPart <strong>int unsigned <\/strong>DEFAULT NULL,<\/address>\n<address>NombInscr <strong>int unsigned<\/strong> DEFAULT NULL,<\/address>\n<address>&#8230;<\/address>\n<address>) ENGINE=InnoDB<\/address>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>Une requ\u00eate, qui fait la soustraction entre NombInscr et NombPart, pour remplir une autre table \u00e0 la vol\u00e9e\u00a0:<\/p>\n<p>&nbsp;<\/p>\n<address>CREATE TABLE &#8230;<\/address>\n<address>SELECT \u2026 <strong>NombInscr &#8211; NombPart <\/strong>as NombAbs &#8230;<\/address>\n<address>FROM\u00a0\u2026\u00a0;<\/address>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>Et l\u00e0, c&rsquo;est le drame&#8230;<\/p>\n<address><span style=\"color: #ff0000;\"><strong>ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in &lsquo;(NombInscr \u2013 NombPart)&rsquo;<\/strong><\/span><\/address>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>Apr\u00e8s quelques tests, le probl\u00e8me est identifi\u00e9, il vient de la soustraction\u00a0: SELECT \u2026 <strong>NombInscr &#8211; NombPart <\/strong>.<\/p>\n<p>Pour faire simple, on a donc un entier non sign\u00e9 qui est retranch\u00e9 d&rsquo;un autre entier non sign\u00e9 et le tout ne rentre pas dans un entier long non sign\u00e9&#8230; \u00e7a ressemble \u00e0 un probl\u00e8me de signes \ud83d\ude42<\/p>\n<p>&nbsp;<\/p>\n<p>Un coup d\u2019\u0153il dans la table montre rapidement que les donn\u00e9es ne sont pas coh\u00e9rentes <em>ie NombInscr &lt; NombPart<\/em> ce qui implique un r\u00e9sultat n\u00e9gatif qui ne peut \u00eatre g\u00e9r\u00e9 dans une colonne non sign\u00e9e ie le BIGINT UNSIGNED du message d&rsquo;erreur.<\/p>\n<p>En effet, les 2 colonnes \u00e9tant de type entier non sign\u00e9, le r\u00e9sultat de l&rsquo;op\u00e9ration est donc g\u00e9r\u00e9 avec le plus grand type d&rsquo;entier (BIGINT) mais en mode non sign\u00e9 (sic) d&rsquo;o\u00f9 mon probl\u00e8me.<\/p>\n<p>Qu&rsquo;\u00e0 cela ne tienne, il suffit juste de s&rsquo;assurer que le r\u00e9sultat est toujours positif et le probl\u00e8me est r\u00e9gl\u00e9 (?).<\/p>\n<p>Essayons la fonction <a href=\"http:\/\/dev.mysql.com\/doc\/refman\/5.5\/en\/mathematical-functions.html#function_abs\" target=\"_blank\">ABS<\/a> par exemple<\/p>\n<p>&nbsp;<\/p>\n<address>SELECT \u2026 <strong>ABS(NombInscr &#8211; NombPart) <\/strong>as NombAbs &#8230;<\/address>\n<address>FROM\u00a0\u2026\u00a0;<\/address>\n<address><span style=\"color: #ff0000;\"><strong>ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in &lsquo;(NombInscr \u2013 NombPart)&rsquo;<\/strong><\/span><\/address>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>pas mieux \ud83d\ude41<\/p>\n<p>La fonction ABS, s&rsquo;appliquant apr\u00e8s la soustraction, le probl\u00e8me reste donc le m\u00eame.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<h2>Quelles solutions\u00a0?<\/h2>\n<p>&nbsp;<\/p>\n<p>Dans mon contexte, plusieurs contournements du probl\u00e8me s&rsquo;offrent \u00e0 moi<\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li>Corriger les probl\u00e8mes d&rsquo;incoh\u00e9rence dans la table (malheureusement pas si simple)<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul>\n<li>Ne faire le calcul que lorsque <em>NombInscr<\/em> est sup\u00e9rieur \u00e0 <em>NombPart<\/em> (et tant pis pour les donn\u00e9es non coh\u00e9rentes)\u00a0:<\/li>\n<\/ul>\n<address>SELECT &#8230; NombInscr &#8211; NombPart as NombAbs<\/address>\n<address>FROM \u2026<\/address>\n<address><strong>WHERE NombInscr &gt;= NombPart ;<\/strong><\/address>\n<p>&nbsp;<\/p>\n<ul>\n<li>Faire le calcul que lorsque <em>NombInscr<\/em> est sup\u00e9rieur \u00e0 <em>NombPart<\/em> et afficher NULL (ou autre chose) sinon\u00a0:<\/li>\n<\/ul>\n<address>SELECT &#8230; <strong>IF(NombInscr &gt;= NombPart, NombInscr \u2013 NombPart, NULL)<\/strong> as NombAbs<\/address>\n<address>FROM \u2026\u00a0;<\/address>\n<p>&nbsp;<\/p>\n<ul>\n<li>Faire le calcul \u00ab\u00a0dans le bon sens\u00a0\u00bb<em> {update @Cyril}<\/em>:<\/li>\n<\/ul>\n<address>SELECT &#8230; <strong>IF(NombInscr &gt;= NombPart, NombInscr &#8211; NombPart, &#8211; (<strong>NombPart<\/strong> &#8211; <strong>NombInscr<\/strong>))<\/strong> as NombAbs<\/address>\n<address>FROM \u2026\u00a0;<\/address>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>Il est aussi possible de s&rsquo;attaquer de mani\u00e8re frontale au probl\u00e8me, en jouant avec le transtypage\u00a0:<\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li>Avec la fonction <a href=\"http:\/\/dev.mysql.com\/doc\/refman\/5.5\/en\/cast-functions.html#function_cast\" target=\"_blank\">CAST<\/a><\/li>\n<\/ul>\n<address>SELECT &#8230; <strong>CAST(NombInscr AS signed) &#8211; CAST(NombPart AS signed)<\/strong> AS NombAbs<\/address>\n<address>FROM &#8230; ;<\/address>\n<p>&nbsp;<\/p>\n<ul>\n<li>Avec du transtypage implicite<\/li>\n<\/ul>\n<address>SELECT &#8230; <strong>(NombInscr+0.0 &#8211; NombPart+0.0)<\/strong> as NombAbs<\/address>\n<address>FROM \u2026 ;<\/address>\n<p>&nbsp;<\/p>\n<ul>\n<li>Avec du transtypage explicite <em>{update @armenweb}<\/em><\/li>\n<\/ul>\n<address>SELECT &#8230; <strong>(CAST(<\/strong><strong>NombInscr AS DECIMAL(20, 0)) &#8211; CAST(NombPart AS DECIMAL(20, 0)))<\/strong> as NombAbs<\/address>\n<address>FROM \u2026 ;<\/address>\n<p>&nbsp;<\/p>\n<p>Une autre mani\u00e8re de faire (plus classe?) est de g\u00e9rer ce probl\u00e8me au niveau serveur, en initialisant la variable <a href=\"http:\/\/dev.mysql.com\/doc\/refman\/5.5\/en\/server-sql-mode.html\" target=\"_blank\">SQL_MODE<\/a> (qui permet de modifier le comportement du serveur) avec la valeur\u00a0 <a href=\"http:\/\/dev.mysql.com\/doc\/refman\/5.5\/en\/server-sql-mode.html#sqlmode_no_unsigned_subtraction\" target=\"_blank\">NO_UNSIGNED_SUBTRACTION<\/a><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<address><strong>SET SESSION sql_mode = &lsquo;NO_UNSIGNED_SUBTRACTION&rsquo;;<\/strong><\/address>\n<address>SELECT &#8230; NombInscr &#8211; NombPart as NombAbs<\/address>\n<address>FROM &#8230; ;<\/address>\n<p>&nbsp;<\/p>\n<p>Dans ce mode, le r\u00e9sultat est g\u00e9r\u00e9 avec un entier sign\u00e9. Cependant, le souci potentiel est alors de d\u00e9passer l&rsquo;intervalle de validit\u00e9 du BIGINT sign\u00e9 et d&rsquo;avoir l&rsquo;erreur suivante\u00a0:<\/p>\n<address><span style=\"color: #ff0000;\"><strong>ERROR 1690 (22003): BIGINT value is out of range in &lsquo;(NombInscr \u2013 NombPart)&rsquo;<\/strong><\/span><\/address>\n<p>&nbsp;<\/p>\n<p>Pas de m\u00e9thodes miracles donc&#8230;<\/p>\n<p>Pour plus d&rsquo;infos, <a href=\"http:\/\/dev.mysql.com\/doc\/refman\/5.5\/en\/out-of-range-and-overflow.html\" target=\"_blank\">RTFM<\/a> \ud83d\ude42<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>P.S. D\u00e9dicace \u00e0 Clem, \u00e0 qui je c\u00e8de tout les droits relatifs \u00e0 cet article \ud83d\ude09<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Le probl\u00e8me du jour, une table qui contient (entre autre) 2 colonnes de type entier non sign\u00e9 ( NombPart &#038; NombInscr).<br \/>\nUne requ\u00eate, qui fait la soustraction entre NombInscr et NombPart, pour remplir une autre table \u00e0 la vol\u00e9e :<br \/>\nCREATE TABLE &#8230;<br \/>\nSELECT \u2026 NombInscr &#8211; NombPart as NombAbs &#8230;<br \/>\nFROM \u2026 ;<\/p>\n<p>Et l\u00e0, c&rsquo;est le drame&#8230;<br \/>\nERROR 1690 (22003): BIGINT UNSIGNED value is out of range in &lsquo;(NombInscr \u2013 NombPart)&rsquo;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"footnotes":""},"categories":[88],"tags":[],"class_list":["post-1273","post","type-post","status-publish","format-standard","hentry","category-astuce"],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p9LfWW-kx","jetpack-related-posts":[{"id":56,"url":"https:\/\/dasini.net\/blog\/2008\/11\/02\/auto_increment-differences-myisam-innodb\/","url_meta":{"origin":1273,"position":0},"title":"AUTO_INCREMENT: Diff\u00e9rences MyISAM &#8211; InnoDB","author":"Olivier DASINI","date":"2 novembre 2008","format":false,"excerpt":"La clause, AUTO_INCREMENT, permet \u00e0 MySQL de g\u00e9n\u00e9rer un entier unique pour tout nouvel enregistrement d'une table. Cette clause ne peut se mettre que sur les champs de type entier, index\u00e9 et non nul. Elle est donc souvent utilis\u00e9e comme cl\u00e9 primaire. Cependant, sont comportement n'est pas tout \u00e0 fait\u2026","rel":"","context":"Dans &quot;MySQL&quot;","block_context":{"text":"MySQL","link":"https:\/\/dasini.net\/blog\/category\/mysql\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":237,"url":"https:\/\/dasini.net\/blog\/2008\/11\/28\/les-nouveautes-de-mysql-51-part-15\/","url_meta":{"origin":1273,"position":1},"title":"Les nouveaut\u00e9s de MySQL 5.1 &#8212; (part 1\/5)","author":"Olivier DASINI","date":"28 novembre 2008","format":false,"excerpt":"Que de chemin parcouru depuis ce 5 juillet 1999, date de lancement de MySQL 3.23.0. En plus des objectifs de simplicit\u00e9 d'administration, de hautes performances et de fiabilit\u00e9, se sont greff\u00e9es, au fur et \u00e0 mesure, les fonctionnalit\u00e9s les plus demand\u00e9es par les utilisateurs. La nouvelle version du SGBDR open-source\u2026","rel":"","context":"Dans &quot;MySQL&quot;","block_context":{"text":"MySQL","link":"https:\/\/dasini.net\/blog\/category\/mysql\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":430,"url":"https:\/\/dasini.net\/blog\/2009\/01\/29\/influencer-loptimiseur-de-mysql\/","url_meta":{"origin":1273,"position":2},"title":"Influencer l&rsquo;optimiseur de MySQL","author":"Olivier DASINI","date":"29 janvier 2009","format":false,"excerpt":"Il est possible d'influencer l'optimiseur pour qu'il choisisse d'utiliser ou de ne pas utiliser un index particulier. Les clauses \u00e0 placer dans votre requ\u00eate SELECT sont les suivantes: USE INDEX : utilise l'index pass\u00e9 en argument (MySQL ne l'utilisera pas si l'index est plus couteux qu'un full table scan) FORCE\u2026","rel":"","context":"Dans &quot;MySQL&quot;","block_context":{"text":"MySQL","link":"https:\/\/dasini.net\/blog\/category\/mysql\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":453,"url":"https:\/\/dasini.net\/blog\/2009\/02\/18\/optimisation-de-requetes-comprendre-loptimiseur-de-mysql\/","url_meta":{"origin":1273,"position":3},"title":"Optimisation de requ\u00eates: comprendre l&rsquo;optimiseur de MySQL","author":"Olivier DASINI","date":"18 f\u00e9vrier 2009","format":false,"excerpt":"Le but de cet article est d'optimiser une simple requ\u00eate (SELECT avg(Population) FROM city GROUP BY CountryCode) et surtout de comprendre comment l'optimiseur proc\u00e8de, en \u00e9tudiant les r\u00e9sultats donn\u00e9s par les variables qui permettent de surveiller le serveur MySQL.","rel":"","context":"Dans &quot;MySQL&quot;","block_context":{"text":"MySQL","link":"https:\/\/dasini.net\/blog\/category\/mysql\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1746,"url":"https:\/\/dasini.net\/blog\/2017\/01\/11\/configurer-proxysql-pour-mysql-group-replication\/","url_meta":{"origin":1273,"position":4},"title":"Configurer ProxySQL pour MySQL Group Replication","author":"Olivier DASINI","date":"11 janvier 2017","format":false,"excerpt":"Dans un pr\u00e9c\u00e9dent article je vous ai pr\u00e9sent\u00e9 comment d\u00e9ployer un cluster MySQL Group Replication, la nouvelle solution de haute disponibilit\u00e9 de MySQL. Ce type d'architecture est souvent utilis\u00e9 avec un composant qui se place entre l'application et le cluster,composant g\u00e9n\u00e9ralement appel\u00e9 proxy (quelque chose) ou router quelque chose. Dans\u2026","rel":"","context":"Dans &quot;Group Replication&quot;","block_context":{"text":"Group Replication","link":"https:\/\/dasini.net\/blog\/category\/group-replication\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/dasini.net\/blog\/wp-content\/uploads\/MySQL_Group_Replication_and_ProxySQL.png?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":1363,"url":"https:\/\/dasini.net\/blog\/2013\/01\/08\/full-table-scan-vs-full-index-scan-part1-2\/","url_meta":{"origin":1273,"position":5},"title":"Full table scan vs Full index scan part1-2","author":"Olivier DASINI","date":"8 janvier 2013","format":false,"excerpt":"MySQL utilise un optimiseur \u00e0 base de co\u00fbts. Le plan d\u2019ex\u00e9cution de la requ\u00eate choisit est celui dont le co\u00fbt est le plus faible. Ce dernier peut \u00eatre visualis\u00e9 gr\u00e2ce \u00e0 la variable Last_query_cost. Son unit\u00e9 est le co\u00fbt (encore lui) des acc\u00e8s al\u00e9atoires en lecture de pages de 4ko.\u2026","rel":"","context":"Dans &quot;optimisation&quot;","block_context":{"text":"optimisation","link":"https:\/\/dasini.net\/blog\/category\/optimisation\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/posts\/1273","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/comments?post=1273"}],"version-history":[{"count":12,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/posts\/1273\/revisions"}],"predecessor-version":[{"id":1286,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/posts\/1273\/revisions\/1286"}],"wp:attachment":[{"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/media?parent=1273"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/categories?post=1273"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/tags?post=1273"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}