Mysql: No se puede escanear un nulo en una * cadena

Creado en 28 feb. 2013  ·  15Comentarios  ·  Fuente: go-sql-driver/mysql

Solía ​​usar el código de Google Code. Después de actualizar al último código en el maestro, recibo el siguiente error que no recibí anteriormente:

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

Investigaré más, pero tal vez mientras tanto, ¿ya saben algo sobre esto?

wontfix

Comentario más útil

Dado que esta página todavía aparece bastante alta en los resultados de búsqueda, mis dos centavos:

También puede resolverlo en la parte donde, en mi opinión, el problema realmente radica: el nivel de abstracción de la base de datos. Puede solucionar este problema haciendo lo siguiente:

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

De esta manera, si name contiene NULL, se sustituye por una cadena vacía al escanear. Coalesce cuenta con un amplio apoyo.

Todos 15 comentarios

El código antiguo devolvía un []byte vacío para NULL que hacía imposible distinguir un NULL de una cadena vacía.
Consulte el número 20 para obtener más detalles.

El paquete database/sql devuelve el error debido a este objetivo:

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

Debe usar http://golang.org/pkg/database/sql/#NullString si la columna puede contener valores NULL

Gracias, eso tiene sentido.

Casi quiero una forma de configurar la biblioteca para que me dé el comportamiento anterior. De alguna manera, el "valor cero como predeterminado" de Go tiene mucho sentido y elimina una tonelada de código repetitivo. Me gustaría poner eso en un solo lugar, de forma configurable, en lugar de esparcirlo por todas partes en mi código donde podría encontrar un NULL. Usar NullString, etc. es bastante feo en cuanto a código.

NULL es solo una pesadilla y quiero deshacerme de los NULL. Defino explícitamente cada columna en _my_ tablas como NOT NULL, pero ocasionalmente un comando como SHOW PROCESSLIST va a tener un NULL, y mi código simplemente no le importa; En su lugar, quiero una cadena vacía. Solo usaré un NullString, ignoraré su propiedad .Valid y obtendré su .String, que estará vacío si la columna es NULL.

Ser capaz de decirle al controlador que convierta NULL en valor cero para el tipo (o, en realidad, supongo que lo que realmente haría es omitir el escaneo de la columna en la variable) reduciría una gran cantidad de problemas difíciles y propensos a errores (y no- a prueba de futuro) funcionan para mí. O, si no quiero todo el código repetitivo, puedo arriesgarme a que la columna a) no sea anulable b) permanezca así para siempre.

También prefiero que el paquete database / sql siga la política de "valor cero predeterminado" de Go. Aún puede diferenciarse con los tipos Null * si es necesario, pero desafortunadamente, la decisión de diseño se tomó de esta manera. Tal vez lo cambien en Go2 (+1 de mí por eso).
Por ahora no tengo ningún plan para agregar una opción de controlador para eso. Comparado con PostgreSQL, el protocolo ya es un desastre (supongo que es más eficiente). No quiero confundir al conductor aún más.
Un str = nullStr.Value más por cadena escaneada es el mal menor por ahora.

Intenté agregar una opción a cero NULL valores: https://github.com/Go-SQL-Driver/MySQL/tree/zeroNULL
Pero no es posible a nivel de conductor. Si establece el valor cero en []byte{} , puede escanearlo a string y []byte pero no a tipos numéricos. Si lo configura en 0 , puede escanearlo a tipos numéricos pero obtiene "0" como string / []byte .

No entiendo muy bien cómo escanea el controlador, pero en lugar de
configurando dest [i] a algo, ¿qué pasa si el controlador simplemente omite la configuración?
dest [i]?

dest es básicamente una porción de []interface{} . El valor predeterminado de interface{} es nil . Entonces, omitir la configuración dest[i] tiene el mismo resultado que configurar dest[i]=nil

Actualicé la rama. Puede probarlo usted mismo si lo desea.

Parece perfecto para mis necesidades y lo probaré la próxima vez que actualice nuestro
copia del controlador.

Otra solución me vino a la mente:
Simplemente use [] byte en lugar de cadena. La conversión de un byte nulo - [] da como resultado una cadena vacía:

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

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

Tal vez mantenga esto abierto, tal vez sea bueno para los Ejemplos

Solución: https://github.com/guregu/null

Dado que esta página todavía aparece bastante alta en los resultados de búsqueda, mis dos centavos:

También puede resolverlo en la parte donde, en mi opinión, el problema realmente radica: el nivel de abstracción de la base de datos. Puede solucionar este problema haciendo lo siguiente:

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

De esta manera, si name contiene NULL, se sustituye por una cadena vacía al escanear. Coalesce cuenta con un amplio apoyo.

No entiendo por qué arroja una excepción cuando la cadena es nula

Este ejemplo me funciona

Puede pasar un puntero de cadena para tratarlo así:

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

Funciona bien para mí.

Además del gran comentario de @Dynom , creo que aún vale la pena mencionar que el tipo sql.NullString es útil si desea abordar el problema en el destino del Scan (que veo como el lado Go del nivel de abstracción de la base de datos).

Además, conserva la capacidad de distinguir entre un nil y una cadena vacía .

Con nullstring, se requiere que el desarrollador cree un mapa vo si desea mostrar la información como un json, por ejemplo. No hay problema aquí, es un enfoque bueno y correcto pero no tiene sentido para todos los casos, entonces puede ser un trabajo adicional por una limitación de idioma.

¿Fue útil esta página
0 / 5 - 0 calificaciones