我正在使用
运行Go查询stmt, err := db.Prepare(sqlstring)
if err != nil{
log.Fatal(err)
}
defer stmt.Close()
这是sql字符串吗?是'安'
select
k_ele.value as kanji, id as k_ele_id,
NULL as r_ele_id, NULL as r_ele_val,
NULL as gloss_id, NULL as gloss_val
from k_ele where value like ?
UNION ALL
select
k_ele.value as kanji, NULL as k_ele_id,
r_ele.id as r_ele_id, r_ele.value as r_ele_val,
NULL as gloss_id, NULL as gloss_val
from
r_ele, k_ele where k_ele.value like ? and k_ele.fk = r_ele.fk
UNION ALL
select
k_ele.value as kanji, NULL as k_ele_id,
NULL as r_ele_id, NULL as r_ele_val,
gloss.id as gloss_id, gloss.value as gloss_val
from
sense, gloss, k_ele
where
k_ele.value like ? and
k_ele.fk = sense.fk and
gloss.fk = sense.id;
这个查询可以通过控制台上的sqlite3和SQLite的数据库浏览器很好地使用,并返回8行甚至for循环中的go代码循环8次。
问题在于
期间rows.Scan()
没有任何列值存储在变量中,除了每行中出现的汉字(因为它在每一行中),但在log.Println()中打印出的只是汉字。
rows, err := stmt.Query(parameter,parameter,parameter)
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var kanji, r_ele_val, gloss_val string
var k_ele_id, r_ele_id, gloss_id int
rows.Scan(&kanji,&k_ele_id,&r_ele_id,&r_ele_val,&gloss_id,&gloss_val)
log.Println(kanji,k_ele_id, r_ele_id,r_ele_val,gloss_id,gloss_val)
}
这是输出(这是?因为我的cmd无法打印日文字符(如果?发送到我的浏览器,它将正确显示该字符)
2015/02/11 22:18:42 ? 105921 0 0
2015/02/11 22:18:42 ? 0 0 0
2015/02/11 22:18:43 ? 0 0 0
2015/02/11 22:18:43 ? 0 0 0
2015/02/11 22:18:43 ? 0 0 0
2015/02/11 22:18:43 ? 0 0 0
2015/02/11 22:18:43 ? 0 0 0
2015/02/11 22:18:43 ? 0 0 0
奇怪的是,如果我改变列的顺序,例如首先在select语句中放置gloss_id,gloss_val。 每个变量都会被存储0,甚至在gloss_id有值之前都会存储汉字。 (这些是相同的数据集)
2015/02/11 22:23:12 0 0 0
2015/02/11 22:23:12 0 0 0
2015/02/11 22:23:13 ? 0 0 197326 cheap
2015/02/11 22:23:13 ? 0 0 197327 rash
2015/02/11 22:23:13 ? 0 0 197328 thoughtless
2015/02/11 22:23:13 ? 0 0 197329 careless
2015/02/11 22:23:13 ? 0 0 197330 indiscreet
2015/02/11 22:23:13 ? 0 0 197331 frivolous
sql在sqlite3中工作得很好,Golang for循环也运行正确的次数。这是数据的样子。
我不确定这是一个错误还是我正在做的事情有问题?我怀疑这是UNION ALL的一个问题,但我不确定如何让它工作。
编辑:我做了rows.Scan这次返回错误以及打印出列
err := rows.Scan(&kanji,&k_ele_id,&r_ele_id,&r_ele_val,&gloss_id,&gloss_val)
if err != nil {
log.Print("rows.Column(): ")
log.Println(rows.Columns())
log.Println(kanji,k_ele_id, r_ele_id,r_ele_val,gloss_id,gloss_val)
log.Fatal(err)
}
2015/02/12 22:38:56 rows.Column():
2015/02/12 22:38:56 [kanji k_ele_id r_ele_id r_ele_val gloss_id gloss_val] <nil>
2015/02/12 22:38:56 ? 105921 0 0
2015/02/12 22:38:56 sql: Scan error on column index 2: converting string "<nil>"
to a int: strconv.ParseInt: parsing "<nil>": invalid syntax
错误消息表示尝试在列索引2(r_ele_id)中将字符串转换为int但是r_ele_id已经不是int(如我的架构图片中所示)?由于需要对此查询使用UNION ALL,因此每行中都会有NULL,我相信我需要为* id类型使用类型NullInt64而不是int。现在试试这个并报告回来
答案 0 :(得分:0)
Rows.Scan不会在不抛出错误的情况下将值扫描到int和string类型。要使用的正确类型是sql.NullInt64和sql.NullString,这些类型将正确保存值并具有bool val,用于检查它是否为nil。