javascript - Knex:嵌套原始查询,转义“?” 特点
问题描述
我正在尝试将 Postgresql LTREE 与 knex 一起使用。
为了管理它,我必须使用 knex 的原始查询,因为显然 LTREE 在 knex 中不是本机的(它特定于 postgresql)
postgresql 和 LTREE 中的操作符是 character ?
,在 knex.raw 中,?
character 是用来绑定值的(众所周知),所以存在冲突。
再一次,这不是问题,因为我们可以使用它\\?
来防止替换 knex?
在原始查询中找到 a 的值。
我的问题是我需要对包含带有\\?
字符的 knex.raw 的查询执行“SELECT EXISTS”,并且在 knex 中我使用 : knex.raw(myQuery).wrap('SELECT EXISTS(', ')')
来执行我的 SELECT EXISTS。所以我嵌套了原始查询,一个用于选择存在,一个myQuery
用于 postgresql ltree 条件。
在执行查询的过程中,第一个 knex.raw 将原来的\\?
转换成 => ?
是正常的,第二个 knex.raw 会做同样的工作,他会找到一个?
并且想要绑定数据但我不给他数据所以 knex 抛出一个错误!
一个解决方案是用这个\\\\?
代替\\?
,第一个 knex.raw 将转换查询,\\?
第二个 knex.raw 将转换最终查询,?
这是我在 postgresql 中想要的(不尝试进行任何绑定)
这很棒!但是myQuery
是由一个通用函数生成的,该函数在带有 SELECT EXISTS 的上下文中调用,但也在没有 SELECT EXISTS 的上下文中调用,如果我\\\\?
只使用一个 knex.raw(没有 SELECT EXISTS 的上下文),它这次也会由 postgresql 引发错误(因为 postgresql 无法识别\\?
)。
是否可以通过所有 knex.raw 转义 `?` 字符?
一个糟糕的解决方案(但一个可行的解决方案)是为生成查询的函数设置一个参数,以精确判断它是否是嵌套原始查询的上下文。
编辑 :
这是我们可以拥有的代码的简单示例:
const functionThatCreatesTheSubQuery = () => {
const condition = knex.raw('columnWithLTree \\? array["Root.Noeud1"]::lquery[]');
return this.where(condition);
};
knex.raw(
knex.select('property')
.from('table')
.where(functionThatCreatesTheSubQuery())
).wrap('SELECT EXISTS (', ')');
这失败了,因为第一个 knex.raw 删除了第一个 double并且 .wrap\\
的\\?
第二个 knex.raw 将等待绑定
解决方案
您将查询生成器knex.raw(...)
作为参数传递给
knex.raw(
// this is not valid parameter
knex.select('property')
.from('table')
.where(functionThatCreatesTheSubQuery())
).wrap('SELECT EXISTS (', ')');
它应该是这样的:
knex.raw('SELECT EXISTS (?)', [
knex.select('property')
.from('table')
.where(functionThatCreatesTheSubQuery())
]);
原始呼叫签名是knex.raw(String, [binding1, binding2, ...])
这是 runkit 示例,它显示问号仍然被转义https://runkit.com/embed/bbtfooz9o1yn
原始查询似乎起作用的原因可能是,当查询构建器knex.raw()
作为第一个参数传递给它时.toString()
,可能会调用它,它将查询构建器转换为纯 SQL 字符串,其中?
-marks 已被取消转义。
推荐阅读
- extendscript - 如何在扩展脚本中使用#include 和面板类型窗口?
- sql - 如何根据条件仅从该表中选择唯一值?
- html - Powershell,IText7 用百分比破坏表格 td 宽度
- python - discord.py 将机器人活动设置为自定义活动
- java - 根据用户自定义输入按单个或多个属性对集合进行排序
- php - 消息:调用未定义的方法 CI_Form_validation::substr()
- android - 在后台颤动音频记录
- reactjs - 移动到另一个选项卡后更改输入值反应 js 挂钩
- ocr - Tesseract/gImageReader OCR:旧文本在单词之间缺少空格
- heroku - 失败的heroku前端部署