【问题标题】:this.parent.acquire is not a function on prepared statementsthis.parent.acquire 不是准备好的语句的函数
【发布时间】:2019-04-15 13:26:42
【问题描述】:

我为我的数据库使用 mssql (https://www.npmjs.com/package/mssql) 模块。通常我使用导致 pg (https://www.npmjs.com/package/pg) 的 postgres 数据库。

我想为 mssql 数据库设置准备好的语句。使用 pg 模块时非常简单。


这就是我使用 pg 的方式:

我设置了我的 databaseManager

const { Pool } = require('pg');
const db = require('../config/database.js');
const pool = new Pool(db);

function queryResponse(result, err) {
  return {
    result,
    err
  };
}

module.exports = async (text, values) => {
  try {
    const result = await pool.query(text, values);
    return queryResponse(result.rows, null);
  } catch (err) {
    return queryResponse(null, err);
  }
};

每当我想查询数据库时,我都可以调用这个模块并传入我的语句和值。待办事项应用的示例是

todos.js(查询文件)

const db = require('../databaseManager.js');

module.exports = {
  getAllTodosFromUser: values => {
    const text = `
        SELECT
            id,
            name,
            is_completed AS "isCompleted"
        FROM
            todo
        WHERE
            owner_id = $1;
    `;

    return db(text, values);
  }
};

我想创建一个等效的 mssql。从文档中我看到该模块与 pg 模块不同。

我将 databaseManager 更改为

const sql = require('mssql');
const config = require('../config/database.js');
const pool = new sql.ConnectionPool(config).connect();

module.exports = async (queryBuilder) => {
    try {
      const preparedStatement = await new sql.PreparedStatement(pool);

      return queryBuilder(sql, preparedStatement, async (query, values) => {
        await preparedStatement.prepare(query);
        const result = await preparedStatement.execute(values);
        await preparedStatement.unprepare();

        return {
            result: result.rows,
            err: null
        };
      });
    } catch (err) {
        return {
            result: null,
            err
        }
    }
};

我的查询文件将传入preparedStatement 对象所需的参数

const db = require('../databaseManager.js');

module.exports = {
  getUserByName: username => db((dataTypes, statementConfigurator, processor) => {
    statementConfigurator.input('username', dataTypes.VarChar);

    const query = `
        SELECT
          *
        FROM
          person
        WHERE
          username = @username;
    `;

    return processor(query, { username });
  })
};

我希望这种方法会返回所需的结果,但我得到了错误

this.parent.acquire 不是函数

不知道我的代码有没有错。如果是,我怎样才能正确设置我准备好的语句?


编辑:

刚刚发现错误来自这行代码

await preparedStatement.prepare(query);

但我认为我从文档中正确理解了它

https://tediousjs.github.io/node-mssql/#prepared-statement

【问题讨论】:

  • 这个问题有帮助吗? stackoverflow.com/questions/30356148/…
  • 我猜你尝试 Acuire 连接时有问题!你将一些对象传递给另一个函数,当事件触发时,它会尝试调用对象的函数,但根本没有找到! 1.首先建议你做一个简单的例子,比如文档github.com/tediousjs/node-mssql 不包装层! 2.然后尝试正确包裹U're层! 3.如果这不起作用将问题添加到您使用的 mssql 库的错误报告中!

标签: node.js sql-server


【解决方案1】:

我认为这个问题应该比 OP 给出的答案多一点解释。解决方案与 OP 已经回答的没有什么不同。

问题仍然存在,池不能从其承诺待定状态解决。所以只能等待。

module.exports = async queryBuilder => {
  try {
    await pool; // Waiting for pool resolve from promise pending state.
    const preparedStatement = await new sql.PreparedStatement(pool);
    // ..
  } catch (err) {
    // ..
  }
};

当您尝试构建准备好的语句时,您将池作为参数传递给其构造函数。在它的构造函数中是下面的line

this.parent = parent || globalConnection

之后,当您准备语句时,流程会导致此line,这将导致问题,因为当时this.parent 的值仍然是一个尚未解决的承诺。

this.parent.acquire(this, (err, connection, config) => {

【讨论】:

    【解决方案2】:

    看来pool 仍然是一个未决的承诺。所以我重命名了变量

    const pool = new sql.ConnectionPool(config).connect();

    poolRequest 并在我的执行函数中等待这个承诺

    module.exports = async (queryBuilder) => {
        try {
          const pool = await poolRequest;
          const preparedStatement = await new sql.PreparedStatement(pool);
    
          // ...
        } catch (err) {
            // ...
        }
    };
    

    这似乎可行,但请随时提供其他解决方案!

    【讨论】:

      猜你喜欢
      • 2014-07-20
      • 1970-01-01
      • 1970-01-01
      • 2013-05-19
      • 1970-01-01
      • 2023-03-19
      • 1970-01-01
      • 2012-03-17
      • 1970-01-01
      相关资源
      最近更新 更多