Раньше я использовал код из Google Code. После обновления кода в мастере до последней версии я получаю следующую ошибку, которую не получал ранее:
sql: Scan error on column index 7: unsupported driver -> Scan pair: <nil> -> *string
Я буду исследовать больше, но, может быть, вы уже что-то знаете об этом?
Старый код возвращал пустой []byte
для значений NULL
что делало невозможным отличить значение NULL
от пустой строки.
См. Подробности в выпуске №20.
Ошибка возвращается пакетом database/sql
из-за этой цели:
* Be flexible with type conversions, but be paranoid about silent
truncation or other loss of precision.
Вы должны использовать http://golang.org/pkg/database/sql/#NullString, если столбец может содержать значения NULL.
Спасибо, в этом есть смысл.
Мне почти нужен способ сконфигурировать библиотеку, чтобы вернуть мне прежнее поведение. В некотором смысле «нулевое значение по умолчанию» Go имеет большой смысл и устраняет массу шаблонного кода. Я бы хотел поместить это в одно место с возможностью настройки вместо того, чтобы разбрасывать его повсюду в моем коде, где я мог бы встретить NULL. Использование NullString и т. Д. Довольно некрасиво с точки зрения кода.
NULL - это просто кошмар, и я хочу избавиться от NULL. Я явно определяю каждый столбец в _my_ таблицах как NOT NULL, но иногда такая команда, как SHOW PROCESSLIST, будет иметь NULL, и мой код просто не заботится; Вместо этого я хочу пустую строку. Я просто собираюсь использовать NullString и проигнорировать его свойство .Valid и просто получу его .String, который будет пустым, если столбец был NULL.
Возможность указать драйверу преобразовать NULL в нулевое значение для типа (или, на самом деле, я думаю, что он действительно сделал бы, так это пропустил сканирование столбца в переменную), уменьшило бы много трудностей и подверженных ошибкам (а не - будущее) работает для меня. Или, если мне не нужен весь шаблонный код, я могу рискнуть, что столбец a) действительно не имеет значения NULL b) останется таким навсегда.
Я бы также предпочел, чтобы пакет database / sql следовал политике Go «нулевое значение по умолчанию». Вы все еще можете различать типы Null *, если вам нужно, но, к сожалению, дизайнерское решение было принято таким образом. Может в Go2 поменяют (+1 от меня за это).
На данный момент я не планирую добавлять для этого драйверы. По сравнению с PostgreSQL протокол уже представляет собой беспорядок (хотя я считаю, что он более эффективен). Не хочу еще больше путать драйвер.
Еще один str = nullStr.Value
на отсканированную строку на данный момент является меньшим злом.
Я попытался добавить опцию к нулевым значениям NULL
: https://github.com/Go-SQL-Driver/MySQL/tree/zeroNULL
Но это невозможно на уровне водителя. Если вы установите нулевое значение на []byte{}
вы можете сканировать его до string
и []byte
но не до числовых типов. Если вы установите его на 0
, вы можете сканировать его до числовых типов, но вы получите «0» как string
/ []byte
.
Я не совсем понимаю, как драйвер на самом деле сканирует, но вместо
установка dest [i] на что-то, что, если драйвер просто пропускает установку
dest [i]?
dest
- это, по сути, срез []interface{}
. Значение по умолчанию interface{}
- nil
. Так что пропуск установки dest[i]
дает тот же результат, что и установка dest[i]=nil
Обновил ветку. Вы можете попробовать это сами, если хотите.
Это идеально подходит для моих нужд, и я попробую его в следующий раз, когда обновлю наш
копия драйвера.
Мне пришло в голову еще одно обходное решение:
Просто используйте [] байт вместо строки. Преобразование байта nil - [] приводит к пустой строке:
string([]byte("")) // => ""
string([]byte(nil)) // => ""
Может быть, оставьте это открытым, может быть, хорошо для примеров
Решение: https://github.com/guregu/null
Поскольку эта страница по-прежнему отображается довольно высоко в результатах поиска, мои два цента:
Вы также можете решить эту проблему в той части, в которой, на самом деле, проблема: на уровне абстракции базы данных. Вы можете обойти эту проблему, выполнив следующие действия:
SELECT
id,
COALESCE(name, '') as name
FROM users
Таким образом, если name
содержит NULL, при сканировании он заменяется пустой строкой. Coalesce широко поддерживается.
Я не понимаю, почему выдает исключение, когда строка равна нулю
Этот пример работает для меня
Вы можете передать строковый указатель, чтобы справиться с этим следующим образом:
var txt *string
checkErr(result.Scan(&txt))
// do something with type *string
Он отлично работает для меня.
Помимо отличного комментария sql.NullString
пригодится, если вы хотите решить проблему в месте назначения Scan
(который я вижу как сторону Go уровня абстракции базы данных).
Кроме того, он сохраняет возможность различать значение nil
и пустую строку .
С нулевой строкой разработчику требуется создать карту vo, если вы хотите отображать информацию, например, в формате json. Здесь нет проблем, это хороший и правильный подход, но он не имеет смысла для всех случаев, поэтому может потребоваться дополнительная работа из-за языковых ограничений.
Самый полезный комментарий
Поскольку эта страница по-прежнему отображается довольно высоко в результатах поиска, мои два цента:
Вы также можете решить эту проблему в той части, в которой, на самом деле, проблема: на уровне абстракции базы данных. Вы можете обойти эту проблему, выполнив следующие действия:
Таким образом, если
name
содержит NULL, при сканировании он заменяется пустой строкой. Coalesce широко поддерживается.