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

Epona發表於2021-06-15

在我們使用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();

完美解決!

本作品採用《CC 協議》,轉載必須註明作者和本文連結
There's nothing wrong with having a little fun.

相關文章