Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql golang sql驱动程序';让我们准备一份声明_Mysql_Go - Fatal编程技术网

Mysql golang sql驱动程序';让我们准备一份声明

Mysql golang sql驱动程序';让我们准备一份声明,mysql,go,Mysql,Go,关于golang的sql驱动程序,下面两个语句之间的区别是什么 // store.DB is *sql.DB type rows, err := store.DB.Query(SQL, args ...) // err != nil defer rows.Close() 及 看起来他们是一样的?有什么细微的区别吗 更新: 我们不需要在db.Prepare之后执行许多stmt.Exec或stmt.Query,在每个Prepare之后只执行一个Exec或Query。当我们使用db.Query或db

关于golang的sql驱动程序,下面两个语句之间的区别是什么

// store.DB is *sql.DB type
rows, err := store.DB.Query(SQL, args ...)
// err != nil
defer rows.Close()

看起来他们是一样的?有什么细微的区别吗

更新

我们不需要在
db.Prepare
之后执行许多
stmt.Exec
stmt.Query
,在每个
Prepare
之后只执行一个
Exec
Query
。当我们使用
db.Query
db.Exec
时,我们将参数传递给方法,而不是使用原始SQL字符串(出于安全考虑)

我找到了一个参考链接:

这两种方法似乎都在使用预先准备好的语句,有什么区别?

这取决于您使用的驱动程序,以及您的DB软件是否支持未准备好的查询

Prepare连接到数据库并创建一个绑定到该数据库连接的prepared语句。执行时,它检查该连接是否仍然可用,如果不可用,则创建一个新连接,重新准备函数,然后运行它

编辑:注意,如果一次只有一个例程连接到数据库,并且使用不同的参数反复运行相同的查询,那么Prepare可以更快,因为它将查询存储在数据库端。然而,其他例程的连接劫持否定了这一点,如果您只使用了一次查询,那么Prepare对您完全没有好处

查询根据驱动程序执行以下两项操作之一。如果驱动程序从
Open()
返回的
Conn
类型也有一个
Query()
方法,因此支持直接查询,那么
sql.Query()
直接调用该方法并返回其结果。如果
Conn
没有
Query()
方法,
sql.Query()
准备一条语句,然后执行它


例如,PostgreSQL的
pq
驱动程序(github.com/lib/pq)有一个
Query()
方法。这个方法准备和执行,就像
sql
包所做的那样,但也有一个替代方法:如果查询没有参数,它使用
simpleQuery
接口执行,包注意到这个接口比准备和执行周期要快得多。

差异可能很微妙,有时很重要,有时实际上根本不存在

一般而言,一份准备好的报表1。与服务器一起准备(SQL解析、生成执行计划等),2。使用附加参数执行,然后执行3。关门了。它允许您使用每次传入的不同参数重用相同的SQL,它可以帮助防止SQL注入,可以提供一些性能增强(特定于驱动程序/协议,YMMV)并防止重复步骤,如上面准备步骤中的执行计划生成和SQL解析

对于编写源代码的人来说,准备好的语句可能比连接字符串并将其发送到DB服务器更方便

DB.Query()
方法将SQL作为字符串和零个或多个参数(与
Exec()
QueryRow()
一样)。没有附加参数的SQL字符串将精确查询您编写的内容。但是,如果提供了一个带有占位符和附加参数的SQL字符串,则会在后台为您准备一条语句

DB.Prepare()

就两者之间的差异以及为什么使用其中一种或另一种而言,有一些事情值得思考

您可以使用不带参数的
DB.Query()
。这可能非常有效,因为它可以绕过prepare语句必须经过的prepare-->execute-->close序列

您还可以将它与其他参数和查询字符串中的占位符一起使用,它将在前面提到的封面下执行一条准备好的语句。这里潜在的问题是,当您进行大量查询时,每一个查询都会产生一个幕后准备的语句。由于涉及到额外的步骤,这可能会非常低效,因为它会在每次执行该查询时重新准备、执行和关闭

使用显式的prepared语句,您可能会避免这种低效,因为您正试图使用可能不同的参数重用先前准备的SQL

但这并不总是像你预期的那样有效。。。由于底层连接池由db/sql管理,所以您的“数据库连接”相当虚拟。
DB.Prepare()。如果你一次又一次地使用同一个事先准备好的语句,那么你可能在不知不觉中也在一次又一次地准备它。很明显,当你面对拥挤的交通时,这一点很容易被发现

很明显,在什么情况下使用哪一个取决于您的具体用例,但我希望上面的细节能够帮助您充分澄清,以便您能够在每种情况下做出最佳决策

更新 鉴于OP中的更新,当查询只需要执行一次时,基本上没有区别,因为带有参数的查询是作为幕后准备的语句来完成的

使用直接方法,例如
DB.Query()
及其类似方法,而不是显式使用预先准备好的语句,因为这样会使源代码更加简单

由于在本例中,准备好的语句是出于安全原因而使用的,因此可能值得通过其他方式处理安全问题,并使用明文查询,因为
// store.DB is *sql.DB type
stmt, err := store.DB.Prepare(SQL)
// err != nil
defer stmt.Close()

rows, err := stmt.Query(args ...)
// err != nil
defer rows.Close()