Пустое поле в Go
В таблице поле может не иметь значения. В Go обычную строку для такого случая не берут: нулевая строка и пустое значение в базе разные вещи.
Для текста используют sql.NullString:
в нем лежит строка и флаг Valid.
Если флаг ложный, в базе был NULL,
и текст из поля String не считают
настоящим значением.
Создадим таблицу с необязательным названием и вставим пустое поле:
package main
import (
"database/sql"
"fmt"
"log"
"os"
_ "modernc.org/sqlite"
)
func main() {
os.Remove("shop.db")
db, err := sql.Open("sqlite", "shop.db")
if err != nil {
log.Fatal(err)
}
defer db.Close()
err = db.Ping()
if err != nil {
log.Fatal(err)
}
_, err = db.Exec(`
CREATE TABLE goods (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT,
price REAL NOT NULL
)
`)
if err != nil {
log.Fatal(err)
}
_, err = db.Exec(
`INSERT INTO goods (title, price) VALUES (?, ?)`,
nil, 5.0,
)
if err != nil {
log.Fatal(err)
}
var title sql.NullString
err = db.QueryRow(
`SELECT title FROM goods WHERE id = ?`,
1,
).Scan(&title)
if err != nil {
log.Fatal(err)
}
if title.Valid {
fmt.Println("title", title.String)
} else {
fmt.Println("no title")
}
}
На экране "no title". Флаг
Valid показал, что значения
не было.
Запишем название и прочитаем его снова:
package main
import (
"database/sql"
"fmt"
"log"
"os"
_ "modernc.org/sqlite"
)
func main() {
os.Remove("shop.db")
db, err := sql.Open("sqlite", "shop.db")
if err != nil {
log.Fatal(err)
}
defer db.Close()
err = db.Ping()
if err != nil {
log.Fatal(err)
}
_, err = db.Exec(`
CREATE TABLE orders (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT,
qty INTEGER NOT NULL,
price REAL NOT NULL
)
`)
if err != nil {
log.Fatal(err)
}
_, err = db.Exec(
`INSERT INTO orders (title, qty, price) VALUES (?, ?, ?)`,
"cup", 2, 4.0,
)
if err != nil {
log.Fatal(err)
}
var title sql.NullString
err = db.QueryRow(
`SELECT title FROM orders WHERE id = ?`,
1,
).Scan(&title)
if err != nil {
log.Fatal(err)
}
fmt.Println(title.Valid, title.String)
}
Дана строка goods:
id=1 title=NULL price=5
Скажите, каким будет Valid
после чтения title в
sql.NullString.
Прочитали title в обычную
string, в базе был NULL.
Скажите, чем это отличается от
чтения в sql.NullString.
Нужно вставить заказ без названия,
но с qty и price.
Опишите, какой аргумент передать
за title в запросе вставки.