怎样在QueryBuilder中使用PostgreSQL中的?操作符

在我们使用Laravel的QueryBuilder中的whereRaw()的时候,? 会被当作Bindings来进行处理。但是在PostgreSQL中存在着许多?的操作符。本文将会介绍怎样处理?操作符。

Laravel中whereRaw的基本使用

这个章节中主要介绍whereRaw的基本使用方法whereRaworWhereRaw方法将原生的where注入到你的查询中。这两个方法的第二个参数还是可选项,值还是绑定参数的数组:

$orders = DB::table('orders')
    ->whereRaw('price > IF(state = "TX", ?, 100)', [200])
    ->get();

通过示例代码可以看到whereRaw中的?方法是用来绑定参数的。

PostgreSQL中?相关的使用。

**这个章节主要介绍PostgreSQL中有关?操作符的介绍。在PostgreSQL中的jsonb格式有很多操作符,其中有一个操作符是这样的。?|,表示左边的jsonb数据是否包含右边的jsonb数据中的任意一项。

SELECT '{"a":1, "b":2, "c":3}'::jsonb ?| array['b', 'c']

在whereRaw中使用PostgreSQL的?操作符

很显然,我们直接在whereRaw中使用?|操作符是会报错的。

Student::whereRaw("'{}'::jsonb ?| array[1, 2, 3]")->get();

结果:

Illuminate/Database/QueryException with message 'SQLSTATE[42601]: Syntax error: 7 ERROR:  syntax error at or near "$1"
LINE 1: select * from "students" where '{}'::jsonb $1| array[1, 2, 3...
                                                   ^ (SQL: select * from "students" where '{}'::jsonb ?| array[1, 2, 3])'

我们可以看到在执行查询的时候?已经被替换成binding了无法使用。

解决方案

我们可以使用原始定义的function来代替?|操作符。

select oprname, oprcode from pg_operator where oprname = '?|';

结果如下:

oprname oprcode
?| point_vert
?| lseg_vertical
?| line_vertical
?| jsonb_exists_any
我们可以看到可以将?|jsonb_exists_any方法来替换。
Student::whereRaw("jsonb_exists_any('{}'::jsonb, array[1, 2, 3])")->get();

完美解决!

标签:

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注