Mysql: Impossible de numériser un null dans une *chaîne

Créé le 28 févr. 2013  ·  15Commentaires  ·  Source: go-sql-driver/mysql

J'avais l'habitude d'utiliser le code de Google Code. Après la mise à jour vers le dernier code dans master, j'obtiens l'erreur suivante que je n'avais pas précédemment :

sql: Scan error on column index 7: unsupported driver -> Scan pair: <nil> -> *string

Je vais enquêter davantage, mais peut-être qu'en attendant, vous savez déjà quelque chose à ce sujet ?

wontfix

Commentaire le plus utile

Étant donné que cette page apparaît toujours assez haut dans les résultats de recherche, mes deux cents :

Vous pouvez également le résoudre dans la partie où, imo, se situe réellement le problème : le niveau d'abstraction de la base de données. Vous pouvez contourner ce problème en procédant comme suit :

  SELECT
    id,
    COALESCE(name, '') as name
  FROM users

De cette façon, si name contient NULL, il est remplacé par une chaîne vide lors de l'analyse. Coalesce est largement pris en charge.

Tous les 15 commentaires

L'ancien code renvoyait un []byte vide NULL , ce qui rendait impossible la distinction entre une NULL une chaîne vide.
Voir le numéro 20 pour plus de détails.

L'erreur est renvoyée par le package database/sql cause de cet objectif :

* Be flexible with type conversions, but be paranoid about silent
  truncation or other loss of precision.

Vous devez utiliser http://golang.org/pkg/database/sql/#NullString si la colonne peut contenir des valeurs NULL

Merci, c'est logique.

Je veux presque un moyen de configurer la bibliothèque pour me donner l'ancien comportement. À certains égards, la "valeur zéro par défaut" de Go a beaucoup de sens et élimine une tonne de code passe-partout. J'aimerais en quelque sorte mettre cela à un seul endroit, de manière configurable, au lieu de le disperser partout dans mon code pour que je puisse rencontrer un NULL. L'utilisation de NullString, etc. est assez moche en termes de code.

NULL n'est qu'un cauchemar et je veux me débarrasser des NULL. Je définis explicitement chaque colonne dans _my_ tables comme NON NULL, mais parfois une commande comme SHOW PROCESSLIST va avoir un NULL, et mon code s'en moque ; Je veux une chaîne vide à la place. Je vais simplement utiliser un NullString et ignorer sa propriété .Valid et obtenir simplement son .String, qui sera vide si la colonne était NULL.

Être capable de dire au pilote de convertir NULL en valeur zéro pour le type (ou en fait, je suppose que ce qu'il ferait vraiment, c'est de sauter l'analyse de la colonne dans la variable) réduirait beaucoup de problèmes difficiles et sujets aux erreurs (et non- à l'épreuve du temps) fonctionnent pour moi. Ou, si je ne veux pas tout le code passe-partout, je peux tenter ma chance pour que la colonne a) soit vraiment non nullable b) le restera pour toujours.

Je préférerais également que le package database/sql suive la politique de "valeur zéro par défaut" de Go. Vous pouvez toujours faire la différence avec les types Null* si nécessaire, mais malheureusement, la décision de conception a été prise de cette façon. Peut-être qu'ils le changent en Go2 (+1 de moi pour ça).
Pour l'instant, je n'ai pas l'intention d'ajouter une option de pilote pour cela. Comparé à PostgreSQL, le protocole est déjà un gâchis (difficile, je suppose, plus efficace). Je ne veux pas brouiller encore plus le conducteur.
Un str = nullStr.Value plus par chaîne numérisée est le moindre mal pour le moment.

J'ai essayé d'ajouter une option aux valeurs zéro NULL : https://github.com/Go-SQL-Driver/MySQL/tree/zeroNULL
Mais ce n'est pas possible au niveau du conducteur. Si vous définissez la valeur zéro sur []byte{} vous pouvez le numériser vers string et []byte mais pas vers des types numériques. Si vous le définissez sur 0 , vous pouvez le numériser en types numériques mais vous obtenez "0" comme string / []byte .

Je ne comprends pas très bien comment le pilote scanne réellement, mais au lieu de
régler dest[i] sur quelque chose, que se passe-t-il si le pilote saute simplement le réglage
dest[je]?

dest est essentiellement une tranche de []interface{} . La valeur par défaut de interface{} est nil . Donc sauter le réglage dest[i] a le même résultat que le réglage dest[i]=nil

J'ai mis à jour la branche. Vous pouvez l'essayer par vous-même si vous le souhaitez.

Cela semble parfait pour mes besoins, et je l'essayerai la prochaine fois que je mettrai à jour notre
copie du pilote.

Une autre solution de contournement m'est venue à l'esprit :
Utilisez simplement []byte au lieu de string. La conversion d'un nil-[]byte donne une chaîne vide :

string([]byte(""))  // => ""
string([]byte(nil)) // => ""

http://play.golang.org/p/nivY1yBK3x

Peut-être garder cela ouvert, peut-être bon pour les exemples

Solution : https://github.com/guregu/null

Étant donné que cette page apparaît toujours assez haut dans les résultats de recherche, mes deux cents :

Vous pouvez également le résoudre dans la partie où, imo, se situe réellement le problème : le niveau d'abstraction de la base de données. Vous pouvez contourner ce problème en procédant comme suit :

  SELECT
    id,
    COALESCE(name, '') as name
  FROM users

De cette façon, si name contient NULL, il est remplacé par une chaîne vide lors de l'analyse. Coalesce est largement pris en charge.

Je ne comprends pas pourquoi a levé une exception lorsque la chaîne est nulle

Cet exemple fonctionne pour moi

Vous pouvez passer un pointeur de chaîne pour le traiter comme ceci :

var txt *string
checkErr(result.Scan(&txt))
// do something with type *string

Ça fonctionne bien pour moi.

Outre @Dynom excellent commentaire, je pense qu'il peut toujours être utile de mentionner que le type sql.NullString est pratique si vous souhaitez résoudre le problème de la destination du Scan (que je considère comme le côté Go du niveau d'abstraction de la base de données).

De plus, il préserve la possibilité de faire la distinction entre une nil et une chaîne vide .

Avec nullstring, le dev est obligé de créer une carte vo s'il veut afficher les informations comme un json par exemple. Pas de problème ici, c'est une approche bonne et correcte mais cela n'a pas de sens dans tous les cas, alors cela peut être un travail supplémentaire par une limitation de la langue.

Cette page vous a été utile?
0 / 5 - 0 notes