Javascript Knex:嵌套原始查询,转义“?”字符

Javascript Knex:嵌套原始查询,转义“?”字符,javascript,postgresql,knex.js,ltree,Javascript,Postgresql,Knex.js,Ltree,我正在尝试将Postgresql LTREE与knex一起使用。 为了管理它,我必须使用knex的原始查询,因为LTREE显然不是knex中的原生版本,而是特定于postgresql的 postgresql和LTREE中的运算符是字符?,在knex.raw中是?众所周知,字符用于绑定值,因此存在冲突 这也不是问题,因为我们可以使用\\?为了防止数值替换,knex在哪里找到了一个?在原始查询中 我的问题是,我需要对包含knex.raw的查询进行“选择存在”,并使用\\?字符,在knex中我使用:k

我正在尝试将Postgresql LTREE与knex一起使用。 为了管理它,我必须使用knex的原始查询,因为LTREE显然不是knex中的原生版本,而是特定于postgresql的

postgresql和LTREE中的运算符是字符?,在knex.raw中是?众所周知,字符用于绑定值,因此存在冲突

这也不是问题,因为我们可以使用\\?为了防止数值替换,knex在哪里找到了一个?在原始查询中

我的问题是,我需要对包含knex.raw的查询进行“选择存在”,并使用\\?字符,在knex中我使用:knex.rawmyQuery.wrap'SELECT EXISTS'来执行我的SELECT EXISTS。所以我有嵌套的原始查询,一个用于select exists,一个用于myQuery中的postgresql ltree条件

在执行查询期间,第一个knex.raw将转换原始\\?进入=>?这是正常的,第二个knex.raw会做同样的工作,他会找到一个?我想绑定数据,但我没有给他数据,所以knex抛出了一个错误

一个解决办法是把\\\\?第一个knex.raw将使用\\?转换查询,而不是\\?第二个knex.raw将使用?这就是我在postgresql中想要的,而不需要尝试任何绑定

这太棒了!但是myQuery是由一个泛型函数生成的,该函数在有SELECT EXISTS的上下文中调用,但在没有SELECT EXISTS的上下文中调用,如果我把\\\\?由于只存在一个没有SELECT的knex.raw上下文,因此这次postgresql也会抛出一个错误,因为postgresql无法识别\\

是否可以通过所有knex.raw转义“?”字符? 一个不好但有效的解决方案是将生成查询的函数的参数设置为precise,以确定它是否是嵌套原始查询的上下文

编辑: 下面是一个简单的代码示例:

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删除了\\的第一个双\\?.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.rawString,[binding1,binding2,…]

下面是runkit示例,它显示问号仍然被转义


原始查询似乎可以工作的原因可能是,在某个时候,当查询生成器作为第一个参数传递给knex.raw时,会为其调用.toString,它会将查询生成器转换为纯SQL字符串,其中?-标记未被替换。

听起来好像您做错了什么。从前面移除逃生卡?是在将查询发送到DB驱动程序以同时执行之前完成的,例如postgresql normal?绑定被转换为$1等。。请添加一些代码来说明您的实际问题。@MikaelLepistöI在原始问题中添加一些代码您的代码工作得非常好!!我还认为转换查询的是toString方法。我们应该始终使用绑定。非常感谢。是的,.toString方法不应该用于任何其他用途,可能只是用于某些调试,我甚至使用toSQL进行调试,因为它直接插入到SQL字符串的绑定,这在处理用户输入时非常危险。