当前位置: 首页 > 面试题库 >

golang sql驱动程序的prepare语句

羊舌志
2023-03-14
问题内容

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

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

// 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()

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

更新

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

我发现了一个参考链接:http : //go-database-
sql.org/prepared.html

似乎两种方式都使用了 预处理语句 ,有什么区别?


问题答案:

差异可能是细微的,有时是重要的,有时实际上是不存在的。

通常,一条准备好的语句1.准备服务器(解析SQL,生成执行计划等),2.使用其他参数执行,然后3.关闭。它使您可以重复使用相同的SQL,并且每次都传递不同的参数,它可以帮助防止SQL注入,可以提供一些性能增强(特定于驱动程序/协议,YMMV)并防止重复步骤,例如在执行计划生成和SQL解析中上面的
准备 步骤。

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

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

DB.Prepare()方法显式执行一个准备好的语句,然后将其传递给参数,如:中所示stmt.Exec(...args)

就两者之间的差异以及为什么使用一种或另一种而言,有几件事值得考虑。

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

您还可以将其与其他参数一起使用,并在查询字符串中使用占位符,并且它将在我前面提到的情况下在其后执行准备好的语句。这里的潜在问题是,当您进行多个查询时,每个查询都会导致内部准备好的语句。由于涉及到额外的步骤,因此在每次执行该查询时,它都会重新准备,执行和关闭,因此效率很低。

使用显式的准备好的语句,当您尝试使用可能具有不同参数的重用先前准备的SQL时,可以避免这种效率低下的情况。

但这并不总是能按您预期的那样解决…由于由db /
sql管理的基础连接池,您的“数据库连接”是相当虚拟的。该DB.Prepare()方法将针对特定连接准备该语句,然后在需要执行该连接时尝试恢复该连接,但是如果该连接不可用,它将简单地获取一个可用的连接并重新准备并针对该连接执行。如果您一次又一次地使用相同的准备好的语句,那么您可能会在不知不觉中又一次又一次地准备它。当您处理繁忙的流量时,这显然很明显。

因此,很明显,您在哪种情况下使用哪种取决于您的特定用例,但是我希望上面的详细信息对您有所帮助,以便您可以在每种情况下做出最佳决策。

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

与直接DB.Query()使用预处理语句相比,使用直接方法(例如,及其类似方法),因为这将导致源代码稍微简单一些。

由于在这种情况下,出于安全原因而使用了准备好的语句,因此值得通过其他方式来处理安全问题并改为使用纯文本查询,因为这将提高性能。但是,除非有足够的流量(或预计将来流量会大大增加)以减轻服务器上的负载,否则任何收益都是无关紧要的。再次归结为现实用例。

对于有兴趣在某些指标上准备的语句和直接明文查询之间的差别的人,有一个很好的文章在这里(这也很好地解释很多上述的一个出色的工作)。



 类似资料:
  • 用于cassandra的Datastax Java驱动程序(cassandra-driver-core 2.0.2)支持PreparedStatements以及QueryBuilder API。使用其中一种比另一种有什么特别的优势吗?缺点? 文档:http://www.datastax.com/documentation/developer/java-driver/2.0/common/drive

  • 对于ex,当我的chrome放在Compand提示符中时,会给出路径-/applications/google\chrome.app system.setproperty(“webdriver.chrome.driver”,“/applications/google/chrome.app”);WebDriver driver=new ChromeDriver(); driver.get(“http

  • 代码有什么问题调试时有很多错误。我正在为一个单例类编写代码以连接数据库mysql。 这是我的代码 我是java新手。请帮忙。

  • 搜索上下文是selenium中最超级的接口,它由另一个称为网络驱动程序的接口扩展。 -所有搜索上下文和Web驱动程序接口的抽象方法都在远程WebDriver类中实现。 -所有与浏览器相关的类,如Firefox驱动程序、Chrome驱动程序等,都扩展了远程Webdriver类。 根据上面的stmt,远程web驱动程序类如何为搜索上下文接口和web驱动程序接口中定义的所有抽象方法给出定义。因为功能驱动

  • 我在使用DataStax php驱动程序1.0.0-rc和Cassandra 2.2.3的Prepared Statements时遇到了一个奇怪的错误。我在这一行遇到了一条异常: 我看到了这个错误: 下面是用于与Cassandra通信的类存根: 如果我将Simple Statemetn与标准select查询一起使用,它会起作用。 有什么建议吗?

  • 我试图通过网络驱动程序在“http://www.kayak.co.in/?ispredir=true”中选择入住和退房时间。无法选择任何日期。请帮帮我。