转义 PostgreSQL 字符串值
Posted
技术标签:
【中文标题】转义 PostgreSQL 字符串值【英文标题】:Escape PostgreSQL string values 【发布时间】:2019-01-21 14:54:21 【问题描述】:我正在尝试向我的 postgres 数据库中插入超过 70k 的值。但是,每一行都有不同类型的特殊字符。当我插入时,我得到了通常的错误。例如:
syntax error at or near ".5"
。我正在使用模块 pg-promise。在我正在使用的代码下方:
function pg_insert(x)
var name = x["name"];
var lastName = x["lasname"];
var sql = `insert into table(name, lastname)`;
var values = `values ($name,$lastname)`;
pg.db
.none(sql + values)
.then(data => )
.catch(err =>
console.log(err);
);
任何帮助将不胜感激。
谢谢
【问题讨论】:
是$name
字符串插值吗?如果是,我建议使用参数化查询来避免引用问题和可能的 SQL 注入。
我该怎么做? Nvm,刚刚找到了方法。谢谢!
【参考方案1】:
正如 Lukasz 所说,使用Parameterized Query:
function pg_insert(x)
const name = x['name'];
const lastName = x['lasname'];
const sql = 'insert into table(name, lastname) values ($1, $2)';
const values = [name, lastname];
pg.db
.none(sql, values)
.then(data => )
.catch(err =>
console.log(err);
);
你也可以使用Named Parameters:
function pg_insert(x)
const sql = 'insert into table(name, lasname) values ($name, $lastname)';
pg.db
.none(sql, x)
.then(data => )
.catch(err =>
console.log(err);
);
但是,正如pg-promise
Named Parameters documentation中提到的:
请记住,虽然属性值 null 和 undefined 都被格式化为 null,但当属性不存在时会引发错误。
如果您传递的对象x
中的任何属性不存在(例如x.name
、x.lasname
、 "name": "Joe"
(注意缺少的lasname
属性)),那么上面的命名参数示例代码将产生错误。
正如vitally-t(库创建者)所提到的,pg-promise
中有helper methods 可以帮助解决缺失的数据。但是,如果您不能保证将传递到查询中的数据的形状,并且对添加清理数据所需的代码不感兴趣,那么参数化查询可能是更简单的防故障选择。
由读者决定哪种方法最适合他们的用例。
【讨论】:
Parameterized Queries
的建议可能放错了地方。库pg-promise
本身提供了几种处理缺失值和默认值的方法,从采用此类选项的基本方法as.format
到也适用于此类默认值的helpers
命名空间。无论如何,Parameterzied Queries
在这里不是一个好的选择。【参考方案2】:
如果你正确使用Named Parameters,那么它会起作用:
function pg_insert(x)
pg.db.none('INSERT INTO table(name, lastname) VALUES($name, $lastname)', x)
.then(data => )
.catch(err =>
console.log(err);
);
更新
我还修改了official documentation 以包括以下内容:
警告:永远不要在 ES6 模板字符串中使用
$
语法,因为它们不知道如何为 PostgreSQL 格式化值。在 ES6 模板字符串中,您只能使用以下 4 个选项之一 -$()
、$<>
、$[]
或$//
。
...为了更清楚。
【讨论】:
以上是关于转义 PostgreSQL 字符串值的主要内容,如果未能解决你的问题,请参考以下文章
org.postgresql.util.PSQLException:没有为参数 1 指定值。- Postgres