使用占位符时无法解析传递到 Postgres 函数的语义相同的 JSONB 对象

问题描述 投票:0回答:1

我有两个相同的 JSON 对象。

第一个对象 第二个对象
[{"id": 123,"firstname": "Mike","lastname": "Smith","ani": 123456,"email": "[电子邮件受保护]"}] [{"id": 123,"firstname": "Mike","lastname": "Smith","ani": 123456,"email": "[电子邮件受保护]"}]

但是,在调用 postgres 函数时,postgres(或至少 PgAmdin 4)并没有以相同的方式对待它们...

当我直接从 pgadmin4 调用该函数时,如下所示:

select * from myfunction(123, abc, '[{"id": 123,"firstname": "Mike","lastname": "Smith","ani": 123456,"email": "[email protected]"}]')

注意物体周围的 ' 标记一切正常。

但是,当我从用 Node js 编写的 AWS Lambda 函数调用 postgres 函数时,如下所示:

let callfunction = `SELECT * FROM myfunction($1, $2, $3)`;
const dataResult = await client.query(callfunction, [123, abc, '[{"id": 123,"firstname": "Mike","lastname": "Smith","ani": 123456,"email": "[email protected]"}]']);

这失败了,说:

json 类型的输入语法无效

我认为,它们是相同的函数调用——无论如何,JavaScript 应该构建一个相同的查询。

但是,这个占位符有一些奇怪的地方,因为无论字符、撇号等如何组合,它总是会失败。

我能够让它工作的唯一方法是将对象包含在实际的函数调用本身中,如下所示:

let callfunction = `SELECT * FROM myfunction($1, $2, '[{"id": 123,"firstname": "Mike","lastname": "Smith","ani": 123456,"email": "[email protected]"}]')`;

同样,这“有效”,但在缓解 SQL 注入漏洞方面显然是一个大禁忌......

为什么这个函数调用在参数化时会有这样的行为?

javascript node.js postgresql aws-lambda node-postgres
1个回答
0
投票

我无法重现该问题,该代码确实应该有效。请注意,撇号与错误消息无关,而且它们无论如何都有不同的用途:在 SQL 代码中,它们分隔 SQL 文字并将被转义为

''
,而在 JavaScript 代码中,它们分隔字符串文字并将被转义作为
\'

但是,有两个建议:

  • 使用
    ::json
    指定参数的类型,以确保正确解决任何潜在的
    myfunction
    重载:
    let callfunction = `SELECT * FROM myfunction($1, $2, $3::json)`;
    
  • 使用
    JSON.stringify
    (而不是文字 json 字符串)来确保传递有效的 JSON:
    const value = [
      {"id": 123,"firstname": "Mike","lastname": "Smith","ani": 123456,"email": "[email protected]"}
    ];
    const dataResult = await client.query(
      callfunction,
      [123, abc, JSON.stringify(value)]
    );
    
© www.soinside.com 2019 - 2024. All rights reserved.