带有json数组的Postgresql中的参数化查询

时间:2016-02-02 14:41:53

标签: node.js postgresql node-postgres pg-promise

我想使用参数化查询将array_prepend调用到json []中。我正在使用pg-promise npm包,但是它使用了普通的node-postgres适配器。

我的查询是:

db.query(`update ${schema}.chats set messages =
  array_prepend('{"sender":"${sender}","tstamp":${lib.ustamp()},"body":$1}',messages) where chat_id = ${chat_id}`
 , message));

与" $ 1"相同。

它适用于非参数化查询。

以上代码产生:

  

{[错误:语法错误在或附近" hiya"]

这样做的主要原因是避免sql注入(文档说它们在使用参数化查询时充分逃脱)。

1 个答案:

答案 0 :(得分:2)

您的查询中存在2个问题。

第一个是你使用ES6模板字符串,同时也使用HTML语法的sql格式。

From the library's documentation

  

使用语法$ * propName *定义命名参数,其中*是以下任何开 - 关对:{},(),[],<>,//,因此您可以使用一个喜欢,但请记住,{}也用于ES6模板字符串中的表达式。

因此,您要么从ES6模板字符串更改为标准字符串,要么只需切换到其他变量语法,例如${propName}$/propName/,这样就可以避免冲突。

第二个问题正如我之前在评论中指出的那样,在生成正确的SQL名称时,请使用记录为SQL Names的内容。

以下是查询格式的更简洁方法:

$[propName]

如果您对要执行的查询类型有疑问,最快捷的方法是通过db.query('update ${schema~}.chats set messages = array_prepend(${message}, messages) where chat_id = ${chatId}', { schema: 'your schema name', chatId: 'your chat id', message: { sender: 'set the sender here', tstamp: 'set the time you need', body: 'set the body as needed' } } ); ,它将为您提供确切的查询字符串。

如果您仍想将ES6模板字符串用于其他内容,则可以将字符串更改为:

pgp.as.format(query, values)

这只是一个例子,语法很灵活。请记住不要使用ES6模板字符串格式化将值注入查询,因为ES6模板不知道如何正确格式化JavaScript类型以符合PostgreSQL,只有库知道它。