2015-05-26 14 views
12

... hoặc câu hỏi đánh dấu câu hỏi.jsonb toán tử tồn tại với các truy vấn được tham số

Tôi hiện đang triển khai chức năng tìm kiếm cho cơ sở dữ liệu postgres, trong php, sử dụng loại jsonb mới.

Để đạt được điều này, tôi đang thực hiện các báo cáo đã chuẩn bị với các trình giữ chỗ được đặt tên.

Tuy nhiên tôi đã gặp phải sự cố thú vị trong khi cố gắng sử dụng một số bưu cục mới JSON containment and existence operators cùng với trình giữ chỗ được đặt tên.

Cơ sở của vấn đề là chính các nhà khai thác sử dụng dấu chấm hỏi ? như một phần của cú pháp của họ. tức là

? Chuỗi khóa/phần tử tồn tại trong giá trị JSON không?

?| Có bất kỳ chuỗi khóa/yếu tố nào tồn tại không?

?& Tất cả các chuỗi khóa/yếu tố này có tồn tại không?

Điều này có nghĩa là tôi có các câu lệnh giống như thế này trong PHP.

$sth = $dbh->prepare("SELECT * FROM stuff WHERE meta ? :value"); 
$sth->bindValue(1, $value, PDO::PARAM_STR); 
$sth->execute(); 

Điều này không thành công vì dấu hỏi đang được hiểu là trình giữ chỗ. Để làm việc xung quanh điều này, tôi đã cố gắng để làm cho các nhà điều hành chính nó một tham số được đặt tên như vậy.

$sth = $dbh->prepare("SELECT * FROM stuff WHERE meta :operator :value"); 
$sth->bindValue(1, $operator, PDO::PARAM_STR); 
$sth->bindValue(2, $value, PDO::PARAM_STR); 
$sth->execute(); 

Tuy nhiên điều này chỉ ném những lỗi tương tự như sử dụng các nhà điều hành trần, ví dụ:

ERROR: syntax error at or near \"$1\"1

Có ai khác đi qua vấn đề này hoặc bất cứ ai có thể nghĩ đến một cách giải quyết tốt?

Có cách nào để thoát hoặc vượt qua dấu chấm hỏi để người ta có thể sử dụng các toán tử ngăn chặn và tồn tại của hậu vệ jsonb với các truy vấn tham số PDO không?

Trả lời

18

bạn có thể sử dụng các hàm tương ứng thay vì toán tử (jsonb_exists, jsonb_exists_any, jsonb_exists_all). ví dụ chạy \do+ "?" trong psql để xem tên hàm? nhà điều hành.

hoặc xác định toán tử của riêng bạn mà không có "?" thay vào đó.

Ví dụ:

CREATE OPERATOR [email protected] (LEFTARG = jsonb, RIGHTARG = text, PROCEDURE = jsonb_exists)  
CREATE OPERATOR [email protected]| (LEFTARG = jsonb, RIGHTARG = text[], PROCEDURE = jsonb_exists_any) 
CREATE OPERATOR [email protected]& (LEFTARG = jsonb, RIGHTARG = text[], PROCEDURE = jsonb_exists_all) 

Vì vậy mà người ta có thể sử dụng [email protected], [email protected]|[email protected]& ở vị trí của ?, ?|?& tương ứng. ví dụ.

$sth = $dbh->prepare("SELECT * FROM stuff WHERE meta [email protected] :value"); 
$sth->bindValue(1, $value, PDO::PARAM_STR); 
$sth->execute(); 
+0

Ha! Thực sự đã không nghĩ về điều đó được nêu ra, sẽ thử nó ra ngay bây giờ, cảm ơn nhiều! – Fraser

+0

Brilliant, toán tử định nghĩa là một giải pháp lý tưởng vì nó có nghĩa là tôi có thể sử dụng cùng một cấu trúc mà không cần phải đối phó với bất kỳ cuộc gọi chức năng nào. Thực sự đánh giá cao nó, đã gãi đầu của tôi cho một vài giờ tốt suy nghĩ về nó từ cuối PDO chứ không phải là kết thúc db. Một lần nữa, cảm ơn rất nhiều. – Fraser

+0

Lưu ý.Trong tài liệu không có các hàm như jsonb_exists, jsonb_exists_any, jsonb_exists_all nhưng chúng thực sự hoạt động như jsonb_exists (jsonb, text) – Swayok

Các vấn đề liên quan