使用占位符调用Postgres函数时,语义相同JSONB对象无法解析
问题分析与解决
核心原因
你在参数化查询中传入的是HTML转义后的JSON字符串(包含"实体),但PostgreSQL要求的是原生JSON格式(使用真实双引号")。
在PgAdmin中直接执行SQL时,PgAdmin会自动将"解析为真实双引号,所以JSON格式合法;但参数化查询里,Node.js的pg驱动会原样传递你输入的字符串,PostgreSQL收到的是[{"id": 123,...}],这不符合JSON语法规范,因此报错。
解决办法
有两种安全可靠的修复方式:
传入原生JSON字符串
将HTML转义的"替换为真实双引号,传递合法的JSON字符串:let callfunction = `SELECT * FROM myfunction($1, $2, $3)`; const validJsonStr = '[{"id": 123,"firstname": "Mike","lastname": "Smith","ani": 123456,"email": "fakeemail@f.com"}]'; const dataResult = await client.query(callfunction, [123, abc, validJsonStr]);直接传入JavaScript对象(推荐)
pg驱动支持自动将JS对象序列化为PostgreSQL的JSON类型,无需手动拼接字符串,既安全又简洁:let callfunction = `SELECT * FROM myfunction($1, $2, $3)`; const jsonObj = [{id: 123, firstname: "Mike", lastname: "Smith", ani: 123456, email: "fakeemail@f.com"}]; const dataResult = await client.query(callfunction, [123, abc, jsonObj]);
为什么硬编码能运行?
硬编码时,转义后的字符串直接写在SQL模板中,当SQL发送到PostgreSQL前,相关工具(PgAdmin或驱动)会自动解析"为双引号,让PostgreSQL识别为合法JSON。但这种方式完全绕过了参数化查询的安全防护,存在严重SQL注入风险,绝对不能使用。
内容的提问来源于stack exchange,提问作者Ethan
相关产品推荐
相关产品推荐

