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?
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)) // => ""
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.
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:
De esta manera, si
name
contiene NULL, se sustituye por una cadena vacía al escanear. Coalesce cuenta con un amplio apoyo.