使用Go查询sqlite数据库,但没有任何行被扫描到变量中

时间:2015-02-12 02:42:16

标签: go sqlite

我正在使用

运行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循环也运行正确的次数。这是数据的样子。

Query from DB Browser for SQLite

我不确定这是一个错误还是我正在做的事情有问题?我怀疑这是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。现在试试这个并报告回来

1 个答案:

答案 0 :(得分:0)

Rows.Scan不会在不抛出错误的情况下将值扫描到int和string类型。要使用的正确类型是sql.NullInt64和sql.NullString,这些类型将正确保存值并具有bool val,用于检查它是否为nil。