对于此表,
# \d table
Table "public.table"
Column | Type | Collation | Nullable | Default
------------+-----------------------------+-----------+----------+--------------------
id | uuid | | not null | uuid_generate_v4()
my_field | hstore | | |
Indexes:
"table_pkey" PRIMARY KEY, btree (id)
如何使用lib/pq更新my_field?我尝试关注,
package "main"
import (
"os"
"database/sql"
_ "github.com/lib/pq"
)
func main() {
postgresConn, _ := sql.Open("postgres", os.Getenv("DB_CONN_URL"))
id := "024b54f2-a477-4715-984c-896bf0446dcf"
data := map[string]string{"data": "data"}
postgresConn.QueryRow("UPDATE table SET my_field = $1 WHERE id = $2", data, id)
}
我不确定可以使用哪种其他类型。
答案 0 :(得分:1)
lib/pq支持hstore
,如mkopriva所示,您可以找到信息here。但这可能需要澄清或更好的例子。
首先,此驱动程序中的Hstore
是包含映射的结构:
type Hstore struct {
Map map[string]sql.NullString
}
因此,如果要使用该地图,则首先需要对其进行初始化:
h := hstore.Hstore{}
h.Map = make(map[string]sql.NullString)
然后,您可以使用它,但考虑到地图的格式为[string]sql.NullString
,则需要将value字段强制转换为sql.NullString
(可为空的字符串, golang中的默认字符串不可为空。)为此,您可以编写一个函数来完成该工作:
//ToNullString invalidates a sql.NullString if empty, validates if not empty
func ToNullString(s string) sql.NullString {
return sql.NullString{String: s, Valid: s != ""}
}
现在,您可以执行以下操作:
data := hstore.Hstore{}
data.Map["data"] = ToNullString("data")
_, err = db.Exec(`INSERT INTO table(id, my_field) VALUES ($1, $2)`, data, id)
然后您可以执行以下操作更新hstore的值:
data.Map["data"] = ToNullString("dat")
_, err := postgresConn.Exec(`UPDATE table SET my_field = my_field || $1 WHERE id = $2`, data, id)
请注意,使用update会更新Hstore中的地图,这意味着,如果仅更改value部分,它将更新值;但是如果您更改键和值,它将在您的hstore中添加一对新的(键,值),而不是替换旧的。
为了澄清一点,我放置了一个示例代码来测试其工作方式,该代码应与您的参数一起使用,为了尊重postgreSQL,我刚刚将table
更改为tabl
关键字:
package main
import (
"database/sql"
"fmt"
_ "github.com/lib/pq"
"github.com/lib/pq/hstore"
)
//ToNullString invalidates a sql.NullString if empty, validates if not empty
func ToNullString(s string) sql.NullString {
return sql.NullString{String: s, Valid: s != ""}
}
func main() {
var err error //To handle different errors
postgresConn, _ := sql.Open("postgres", os.Getenv("DB_CONN_URL"))
data := hstore.Hstore{}
data.Map = make(map[string]sql.NullString)
//Inserting the first element with:
//id: "024b54f2-a477-4715-984c-896bf0446dcf"
//my_field :"data => data"
id := "024b54f2-a477-4715-984c-896bf0446dcf"
data.Map["data"] = ToNullString("data")
_, err = postgresConn.Exec(`INSERT INTO tabl(id, my_field) VALUES ($2, $1)`, data, id)
if err != nil {
fmt.Println(err)
}
//Adding a second field in hstore:
//id: "024b54f2-a477-4715-984c-896bf0446dcf"
//my_field :"data => data", "data2 => more_data"
data.Map["data2"] = ToNullString("more_data")
_, err = postgresConn.Exec(`UPDATE tabl SET my_field = my_field || $1 WHERE id = $2`, data, id)
if err != nil {
fmt.Println(err)
}
//Modifying the first value field:
//id: "024b54f2-a477-4715-984c-896bf0446dcf"
//my_field :"data => value, data2 => more_data"
data.Map["data"] = ToNullString("value")
_, err = postgresConn.Exec(`UPDATE tabl SET my_field = my_field || $1 WHERE id = $2`, data, id)
if err != nil {
fmt.Println(err)
}
}
要获取更多信息以从sql的角度使用hstore
,可以看一下here。
PD:请勿使用table
作为表名,因为它是reserved word。
PD2:我仅将postgresConn.Exec()函数用于演示,如果需要准备的语句,请对其进行更改,有关何时使用Exec()或Query()here的更多信息。
PD3:使用地图时,请尝试不要对键和值使用相同的值。