我想使用 Go 和 sqlite 创建一个小型书籍数据库。我从这个建议SQLite 外键示例中获取主要内容并对其进行了一些重新开发。package main import ( "database/sql"... _ "github.com/mattn/go-sqlite3")...db, err := sql.Open("sqlite3", "./foo.db")if err != nil { log.Fatal(err)}defer db.Close()sqlStmt := ` create table books ( id integer primary key autoincrement, title text ); create table booksauthors ( bookid integer references books(id), uthorid integer references authors(id) ON DELETE CASCADE ON UPDATE CASCADE ); create table authors ( id integer primary key autoincrement, fname text, mname text, lname text, unique (fname, mname, lname) on conflict ignore );`因此,我想保留唯一作者的列表并与书籍表保持多对多连接(一本书可能有多个作者,而作者可能写了多个书)。然后我简单地循环添加书籍,获取 LastIndexID 并将其放入连接表(代码减少用于说明,b 是书籍结构):tx, err := db.Begin()if err != nil { log.Fatal(err)}res, err := db.Exec("Insert into books(title) values(?)", b.Title)if err != nil { log.Fatal(err)}b_id, _ := res.LastInsertId()for _, a := range b.Authors { res, err = db.Exec("Insert into authors(fname, mname, lname) values(?, ?, ?)", a.Fname, a.Mname, a.Lname) if err != nil { log.Fatal(err) } a_id, _ := res.LastInsertId() fmt.Println(a_id, b_id, a) res, err = db.Exec("Insert into booksauthors(bookid, authorid) values(?, ?)", b_id, a_id) if err != nil { log.Fatal(err) }}tx.Commit()
2 回答
慕斯王
TA贡献1864条经验 获得超2个赞
作为一个快速的'n'dirty hack,我在添加了一个作者后做了一个选择:
err = db.QueryRow("select id from authors where fname = ? and mname = ? and lname = ?", a.Fname, a.Mname, a.Lname).Scan(&a_id)
if err != nil {
log.Fatal(err)
}
res, err = db.Exec("Insert into booksauthors(bookid, authorid) values(?, ?)", b_id, a_id)
if err != nil {
enter code herelog.Fatal(err)
}
但我仍在寻找更好的答案......
米琪卡哇伊
TA贡献1998条经验 获得超6个赞
我的建议是给SELECT你列出作者和INSERT遗漏的名单。该解决方案很幼稚,但它有效且简单。我不是最新的 SQLite 关系特性,但使用它们并不总是处理外键的最简单方法......。
现在,如果你有一个大批量数据的过程中,做同样的操作,但是通过合并你的书的作者开始,所以你只能有一个SELECT再一个INSERT的事情。
- 2 回答
- 0 关注
- 218 浏览
添加回答
举报
0/150
提交
取消
