引言
数据库/sql
在Go标准sql库中,*Stmt类型的方法定义如下:
func (s *Stmt) Exec(args ...interface{}) (Result, error)
func (s *Stmt) Query(args ...interface{}) (*Rows, error)A新(未命名)语句是由以下人员编写的:
func (db *DB) Prepare(query string) (*Stmt, error)pgx
PreparedStatement类型没有定义任何方法。以下组织编写了一个新的命名准备语句:
func (p *ConnPool) Prepare(name, sql string) (*PreparedStatement, error)在Github评论中,作者更好地解释了pgx与数据库/sql在体系结构上的差异。关于Prepare的文档还指出(重点是我):
准备是幂等的;也就是说,使用相同的名称和sql参数多次调用准备是安全的。这允许代码路径准备和查询/Exec/PrepareEx,而不必担心语句是否已经准备好。
小例子
package main
import (
"github.com/jackc/pgx"
)
func main() {
conf := pgx.ConnPoolConfig{
ConnConfig: pgx.ConnConfig{
Host: "/run/postgresql",
User: "postgres",
Database: "test",
},
MaxConnections: 5,
}
db, err := pgx.NewConnPool(conf)
if err != nil {
panic(err)
}
_, err = db.Prepare("my-query", "select $1")
if err != nil {
panic(err)
}
// What to do with the prepared statement?
}问题(S)
name参数给我的印象是,它可以通过name调用它来执行,但是如何执行呢?Query/Exec方法以某种方式利用了准备好的语句。但是,这些方法不采用name参数。怎么配得上呢?可能的答案
这就是我自己取得的成就:
conn.ExecEx()中的查询体上进行匹配。如果尚未做好准备,将采取下列行动:ps, ok := c.preparedStatements[sql]
if !ok {
var err error
ps, err = c.prepareEx("", sql, nil)
if err != nil {
return "", err
}
}发布于 2019-02-13 20:46:28
@mkopriva指出,sql文本误导了我。这里有双重功能。如果sql变量与c.preparedStatements[sql]映射中的键不匹配,则将准备sql中包含的查询,并为ps指定一个新的*PreparedStatement结构。如果它匹配一个键,ps变量将指向映射的一个条目。
因此,您可以有效地执行以下操作:
package main
import (
"fmt"
"github.com/jackc/pgx"
)
func main() {
conf := pgx.ConnPoolConfig{
ConnConfig: pgx.ConnConfig{
Host: "/run/postgresql",
User: "postgres",
Database: "test",
},
MaxConnections: 5,
}
db, err := pgx.NewConnPool(conf)
if err != nil {
panic(err)
}
if _, err := db.Prepare("my-query", "select $1::int"); err != nil {
panic(err)
}
row := db.QueryRow("my-query", 10)
var i int
if err := row.Scan(&i); err != nil {
panic(err)
}
fmt.Println(i)
}https://stackoverflow.com/questions/54619645
复制相似问题