【问题标题】:node-postgres: how to prepare a statement without executing the query?node-postgres:如何在不执行查询的情况下准备语句?
【发布时间】:2012-09-02 03:18:35
【问题描述】:

我想使用 node-postgres 模块在 postgres 中创建一个“准备好的语句”。我想创建它而不将其绑定到参数,因为绑定将在循环中进行。

documentation 我读到:

query(object config, optional function callback) : Query
If _text_ and _name_ are provided within the config, the query will result in the creation of a prepared statement.

我试过了

client.query({"name":"mystatement", "text":"select id from mytable where id=$1"});

但是当我尝试只传递配置对象中的文本和名称键时,我得到一个异常:

(已翻译)消息绑定了 0 个参数,但准备好的语句需要 1 个

我有什么遗漏吗?如何在不将其绑定到特定值的情况下创建/准备语句以避免在循环的每个步骤中重新准备语句?

【问题讨论】:

    标签: node.js node-postgres


    【解决方案1】:

    您可以为此使用pg-prepared

    var prep = require('pg-prepared')
    
    // First prepare statement without binding parameters
    var item = prep('select id from mytable where id=${id}')
    
    // Then execute the query and bind parameters in loop
    for (i in [1,2,3]) {
      client.query(item({id: i}), function(err, result) {...})
    }
    

    【讨论】:

    • pg-prepared 所做的事情与 OP 所要求的不同。它提供了在查询中使用命名占位符的能力。
    • OP 希望创建准备好的语句,而无需在创建时绑定参数值。这就是使用 pg-prepared 的示例中发生的情况。首先,您在不绑定参数值的情况下创建语句并将其存储在 var item 中。然后你用参数调用它。所以OP可以通过创建没有变量绑定的语句来使用它,然后在循环中使用参数值调用它。
    • 在您的情况下,database 必须一次又一次地准备查询。 OP想要的是通过只准备一次stmt来减轻db。根据接受的答案,如果 pg-prepared 为查询提供唯一的“名称”属性,它可以达到此目的 - cf github.com/brianc/node-postgres/wiki/Prepared-Statements
    【解决方案2】:

    更新:再次阅读您的问题,这就是我认为您需要做的事情。您还需要传递一个“值”数组。

    只是为了澄清;您通常会“准备”您的查询,只需准备您传递给它的对象,而不需要值数组。然后在您通常“执行”查询的地方,在对象中设置值数组并将其传递给查询。如果是第一次,驱动程序会在第一时间为你做实际的准备,然后简单地为其余的迭代做绑定和执行。

    【讨论】:

    • 该解决方案的问题在于,准备好的语句将使用创建时使用的“任何”值执行。使用循环的第一次迭代进行创建也感觉很尴尬
    • 我猜这就是 API 的设计方式,至少这是我从阅读文档并在我自己的一个项目中使用它所得到的。 API 希望您在需要使用查询对象时创建它,然后它会根据它是否知道您在 text 中输入的内容来确定是否需要准备语句。
    【解决方案3】:

    我刚刚找到了 node-postgres 的作者的answer on this issue

    第一次发出命名查询时,使用 node-postgres 一次解析、绑定和执行。发出的每个后续查询 在同一个连接上同名的会自动跳过 “解析”步骤,只重新绑定并执行已经计划好的查询。

    目前 node-postgres 不支持创建命名的方法, 准备好的查询而不执行查询。支持此功能 在 libpq 和客户端/服务器协议(由纯 javascript 绑定),但我没有直接在 API 中公开它。一世 认为这会增加 API 的复杂性而没有任何真正的好处。 由于命名语句绑定到它们所在的客户端 创建,如果客户端断开连接并重新连接或不同 客户端从客户端池返回,命名语句将不会 更长的工作时间(需要重新解析)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-16
      • 1970-01-01
      • 2014-10-14
      • 1970-01-01
      • 1970-01-01
      • 2017-03-15
      • 2018-01-06
      • 2020-03-15
      相关资源
      最近更新 更多