Mysql: Não é possível digitalizar um nulo em uma * string

Criado em 28 fev. 2013  ·  15Comentários  ·  Fonte: go-sql-driver/mysql

Eu costumava usar o código do Google Code. Depois de atualizar para o código mais recente no mestre, estou recebendo o seguinte erro que não recebi anteriormente:

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

Vou investigar mais, mas por enquanto você já sabe algo sobre isso?

wontfix

Comentários muito úteis

Uma vez que esta página ainda aparece bem alta nos resultados de pesquisa, meus dois centavos:

Você também pode resolvê-lo na parte onde, imo, o problema realmente está: O nível de abstração do banco de dados. Você pode contornar esse problema fazendo o seguinte:

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

Desta forma, se name contiver NULL, ele será substituído por uma string vazia durante a varredura. Coalesce é amplamente suportado.

Todos 15 comentários

O código antigo retornava um []byte vazio para NULL valores que tornavam impossível distinguir um NULL de uma string vazia.
Consulte a edição nº 20 para obter detalhes.

O erro é retornado pelo pacote database/sql devido a este objetivo:

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

Você deve usar http://golang.org/pkg/database/sql/#NullString se a coluna puder conter valores NULL

Obrigado, isso faz sentido.

Eu quase quero uma maneira de configurar a biblioteca para me dar o comportamento antigo. De certa forma, o "valor zero como padrão" de Go faz muito sentido e elimina uma tonelada de código clichê. Eu gostaria de colocar isso em um lugar, configurável, em vez de espalhar em todo o meu código para que eu possa encontrar um NULL. Usar o NullString, etc. é muito feio em termos de código.

NULL é apenas um pesadelo e quero me livrar dos NULLs. Eu defino explicitamente cada coluna em _minhas_ tabelas como NOT NULL, mas ocasionalmente um comando como SHOW PROCESSLIST terá um NULL nele, e meu código simplesmente não se importa; Eu quero uma string vazia em vez disso. Vou apenas usar um NullString e ignorar sua propriedade .Valid e apenas obter seu .String, que estará vazio se a coluna for NULL.

Ser capaz de dizer ao driver para converter NULL em valor zero para o tipo (ou na verdade, eu acho que o que realmente faria é pular a varredura da coluna na variável) reduziria muito a dificuldade e a tendência a erros (e não- à prova de futuro) trabalhar para mim. Ou, se não quiser todo o código clichê, posso arriscar que a coluna a) seja realmente não anulável b) permanecerá assim para sempre.

Eu também prefiro que o pacote database / sql siga a política de "valor zero padrão" do Go. Você ainda pode diferenciar com os tipos Nulos * se precisar, mas infelizmente a decisão de design foi feita dessa forma. Talvez eles mudem no Go2 (+1 de mim para isso).
Por enquanto, não tenho planos de adicionar uma opção de driver para isso. Comparado ao PostgreSQL, o protocolo já é uma bagunça (difícil, suponho que seja mais eficiente). Não quero confundir ainda mais o motorista.
Um str = nullStr.Value mais por string escaneada é o mal menor por enquanto.

Tentei adicionar uma opção para zerar NULL valores: https://github.com/Go-SQL-Driver/MySQL/tree/zeroNULL
Mas não é possível no nível do driver. Se você definir o valor zero para []byte{} poderá digitalizá-lo para string e []byte mas não para os tipos numéricos. Se você definir para 0 , poderá digitalizá-lo para tipos numéricos, mas obterá "0" como string / []byte .

Eu não entendo muito bem como o driver faz a varredura, mas em vez de
definindo dest [i] para algo, e se o driver simplesmente pular a configuração
dest [i]?

dest é basicamente uma fatia de []interface{} . O valor padrão de interface{} é nil . Portanto, pular a configuração dest[i] tem o mesmo resultado que definir dest[i]=nil

Eu atualizei o ramo. Você pode experimentar por si mesmo, se quiser.

Parece perfeito para minhas necessidades, e tentarei na próxima vez que atualizar nosso
cópia do driver.

Outra solução alternativa veio apenas à minha mente:
Basta usar [] byte em vez de string. A conversão de um byte nil - [] resulta em uma string vazia:

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

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

Talvez mantenha isso aberto, talvez seja bom para os exemplos

Solução: https://github.com/guregu/null

Uma vez que esta página ainda aparece bem alta nos resultados de pesquisa, meus dois centavos:

Você também pode resolvê-lo na parte onde, imo, o problema realmente está: O nível de abstração do banco de dados. Você pode contornar esse problema fazendo o seguinte:

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

Desta forma, se name contiver NULL, ele será substituído por uma string vazia durante a varredura. Coalesce é amplamente suportado.

Eu não entendo por que lança uma exceção quando a string é nula

Este exemplo funciona para mim

Você pode passar um ponteiro de string para lidar com isso da seguinte maneira:

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

Isso funciona bem para mim.

Além do ótimo comentário do @Dynom , acho que ainda vale a pena mencionar que o tipo sql.NullString é útil se você quiser resolver o problema no destino de Scan (que vejo como o lado Go do nível de abstração do banco de dados).

Além disso, ele preserva a capacidade de distinguir entre um nil e uma string vazia .

Com nullstring, o dev é obrigado a criar um mapa vo se quiser mostrar as informações como um json, por exemplo. Não há problema aqui, é uma abordagem boa e correta, mas não faz sentido para todos os casos, então pode ser um trabalho adicional por uma limitação de idioma.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

albrow picture albrow  ·  7Comentários

AlekSi picture AlekSi  ·  3Comentários

BSick7 picture BSick7  ·  8Comentários

PingGao89 picture PingGao89  ·  3Comentários

knadh picture knadh  ·  6Comentários