web-dev-qa-db-fra.com

La valeur BIGINT UNSIGNED est hors limites

Je reçois l'erreur

La valeur BIGINT UNSIGNED est hors limites dans '(1301980250 - mydb.news_articles.date) '

Lorsque j'exécute la requête

SELECT *, ((1 / log(1301980250 - date)) * 175) as weight FROM news_articles ORDER BY weight;

La suppression de la condition ORDER BY supprime également l'erreur. Comment puis-je le réparer?

Mise à jour: Le champ de date contient l'horodatage Unix (ex: 1298944082). L'erreur a commencé à apparaître après la mise à niveau de MySQL de 5.0.x vers 5.5.x

Avez-vous besoin d'aide?

37
Joyce Babu

J'ai récemment rencontré ce problème et j'ai trouvé la solution la plus raisonnable pour simplement jeter les entiers NON SIGNÉS comme SIGNÉS.

 SELECT *, ((1 / log(1301980250 - cast(date as signed)) * 175) as weight FROM news_articles ORDER BY weight
74
ab5tract

Le problème a été causé par un débordement d'entier non signé comme suggéré par wallyk. Il peut être résolu par

  1. en utilisant SELECT *, ((1 / log((date - 1301980250) * -1)) * 175) as weight FROM news_articles ORDER BY weight; (Celui-ci a fonctionné pour moi) `
  2. Modification du paramètre sql_mode dans my.cnf en NO_UNSIGNED_SUBTRACTION (je n'ai pas vérifié cela)
16
Joyce Babu

Cela peut parfois être dû à des valeurs nulles dans les données.

Utilisez IFNULL pour définir une valeur par défaut (probablement 0 pour un horodatage est une valeur par défaut médiocre et en fait dans ce cas, il vaut mieux exclure les dates nulles dans la clause WHERE)

SELECT (123456 - IFNULL(date, 0)) AS leVar

4
Ian Chadwick

Toute valeur de date après 2011-04-04 22:10:50 PDT (2011-04-05 05:10:50 utc) provoquera cette erreur car cela rendrait l'expression négative.

4
wallyk

vous pouvez peut-être utiliser cast

SELECT *, ((1 / log(1301980250 - cast(date AS SIGNED))) * 175) as weight FROM news_articles ORDER BY weight;

2
fairjm

Personne n'a mentionné que la fonction log () n'est définie que pour des arguments strictement positifs. Surveillez cela lorsque vous utilisez des soustractions dans log ().

Quant à la question d'origine, un facteur clé pour la résolution était de nous dire le type de données pour la colonne date. S'il est NON SIGNÉ, MySQL pourrait ne pas l'aimer.

La règle est que MySQL a un algo arithmétique médiocre et ne peut pas comprendre comment soustraire un opérande B D'un autre A (= faire A-B) quand A est codé sur moins d'octets que B ET B> A.

par exemple. A = 12 et est SMALLINT, B = 13 AS INT, alors MySQL ne peut pas comprendre ce qu'est A-B (-1!)

Pour créer du contenu MySQL, il suffit d'étendre la longueur de codage de l'opérande A. Comment? Utiliser CAST () ou multiplier A par un nombre décimal.

Comme on peut le voir, c'est moins un problème de débordement qu'un problème de manipulation du signe dans l'arithmétique de MySQL. Un microprocesseur, ou mieux, un humain, n'a aucun problème pour effectuer ce type d'arithmétique ...

Utiliser CAST () est le moyen, ou pour faire court, juste provoquer le transtypage implicite en multipliant l'opérande A par 1. (ou 1.0):

par exemple

1.*A - B
2
Fabien Haddadi

Je viens de rencontrer ce problème en faisant une mise à jour sur un champ où le résultat a fini par être inférieur à 0.

Solution: vérifiez qu'aucune de vos mises à jour n'entraîne un résultat inférieur à 0 sur un champ non signé.

0
kojow7