带间隔参数的 Go postgres 准备好的语句不起作用

Car*_*rbs 5 postgresql go

我尝试使用 Go 的 pq 库将以下内容简单地插入到 postgres 数据库中(我正在关注 Let's Go 书,但使用 Postgres 而不是 mySQL):

title := "O snail"
content := "O snail\nClimb Mount Fuji,\nBut slowly, slowly!\n\n - Kobayashi"
expires := "7"

stmt := `INSERT INTO snippets (title, content, created, expires)
    VALUES($1, $2, current_timestamp, current_timestamp + interval '$3 days')`

_, err := m.DB.Exec(stmt, title, content, expires)
Run Code Online (Sandbox Code Playgroud)

但这会引发错误: handlers.go:56: pq: got 3 parameters but the statement requires 2

事实上,如果我只是expires从最后一行中删除并传入 2 个参数,它就会起作用,并且间隔值将被视为“3 天”。

这有什么意义呢?为什么会被$忽略?我认为这是由于一些带有单引号的转义内容造成的,所以我尝试了'\$3 days',但它给出了一个错误pq: syntax error at or near "\"。如果我尝试转义单引号,我也会收到错误\'$3 days\'。有什么建议么?

Tim*_*sen 7

您可以乘以interval '1 day'一个绑定参数,以获得您想要的正确间隔。

stmt := `INSERT INTO snippets (title, content, created, expires)
VALUES($1, $2, current_timestamp, current_timestamp + interval '1 day' * $3)`
Run Code Online (Sandbox Code Playgroud)


bla*_*een 7

您还可以将参数转换为interval完整的间隔字符串并将其作为查询参数传递:

expires := "7 days"

stmt := `INSERT INTO snippets (title, content, created, expires)
    VALUES($1, $2, current_timestamp, current_timestamp + $3::interval)`

_, err := m.DB.Exec(stmt, title, content, expires)

Run Code Online (Sandbox Code Playgroud)

这还使您可以更好地控制如何确定 的值expire,例如使用fmt.Sprintf、 或字符串连接,以防您还想将时间单位作为外部提供的参数。