7

Với khung Chơi 2.1Làm cách nào để tạo một hàm trong PostgreSQL bằng cách sử dụng các diễn biến trong khung công tác Phát?

Tôi đã SQL sau đây được định nghĩa trong quá trình tiến hóa của tôi:

CREATE OR REPLACE FUNCTION idx(myArray anyarray, myElement anyelement) RETURNS int AS $$ 
SELECT i FROM (
    SELECT generate_series(array_lower(myArray,1),array_upper(myArray,1)) 
) g(i) 
WHERE myArray[i] = anyElement 
LIMIT 1; $$ LANGUAGE sql IMMUTABLE; 

Khi tôi thực sự phát triển, tôi nhận được lỗi sau:

We got the following error: ERROR: unterminated dollar-quoted string at or near 
"$$ SELECT i FROM (SELECT generate_series(array_lower(myArray,1), 
array_upper(myArray,1))) g(i) WHERE myArray[i] = anyElement LIMIT 1" Position: 
87 [ERROR:0, SQLSTATE:42601], while trying to run this SQL script: 

tôi đang sử dụng trình điều khiển PostgreSQL phiên bản 9.1-901.jdbc4.

Tôi nhìn vào các bản ghi postgres truy vấn và phát hiện ra rằng chơi đang cố gắng để làm như sau:

LOG: execute <unnamed>: insert into play_evolutions values($1, $2, $3, $4, $5, $6, $7) 
PST DETAIL: parameters: $1 = '1', 
         $2 = 'c834d463ebd9916b0a3388040300a0926514faef', 
         $3 = '2013-03-05 00:00:00', 
         $4 = '-- THE EVOLUTION UP STATEMENTS GO HERE', 
         $5 = '-- THE EVOLUTION DOWN STATEMENTS GO HERE', 
         $6 = 'applying_up', 
         $7 = '' 

Vì vậy, đối với một số lý do chơi đang cố gắng chèn SQL vào một cột văn bản mà không thoát đúng cách. Có ai khác tìm thấy một công việc xung quanh cho điều này? Bạn có nghĩ rằng đây là một vấn đề JDBC và không phải là một vấn đề Play? Ngoài ra, có ai có Liquibase làm việc với Play 2.1 không?

Ngoài ra, chỉ thay đổi $$ thành 'cũng không hoạt động. Trong trường hợp đó, chúng tôi gặp phải một lỗi khác, nhưng chúng tôi vẫn không thể thực hiện sự tiến hóa.

Chỉnh sửa: Tôi đã thêm một ví dụ từ dự án phát mới hoàn toàn mới. Vui lòng tải xuống tại: http://elijah.zupancic.name/files/play_evolution_problem.tar.gz

Để có ví dụ hoạt động, bạn sẽ cần phải tạo cơ sở dữ liệu mới như được hiển thị trong nhận xét đầu tiên về sự tiến hóa 1.sql. Sau đó, bạn sẽ cần phải cấu hình conf/application.conf của bạn để kết nối với postgres trên cổng chính xác và với đúng người dùng.

Tôi vừa thực hiện thử nghiệm nơi tôi cố gắng chèn hàm tạo sql hoàn toàn bên ngoài khung chơi. Ví dụ ở đây: http://elijah.zupancic.name/files/PgCreateFunction.tar.gz <

Nó chỉ ra rằng nó rất dễ tái sản xuất.

EDIT: Nó chỉ ra rằng tôi không thể tái tạo nó trong Java.

+0

Điều bạn đang thấy là kết quả gỡ lỗi từ Pg hiển thị truy vấn được tham số và đối số của nó. Mỗi tham số được gửi riêng rẽ qua giao thức fe/be và không cần phải được khách hàng thoát. Vấn đề bạn thấy ở đây gần như chắc chắn chỉ với biểu diễn gỡ lỗi của Pg về các tham số vô điều kiện bằng cách sử dụng ''''; thông số thực tế sẽ ổn. Nếu nó không thoát được, bạn sẽ thấy một truy vấn SQL lớn với tất cả tham số được thay thế vào nó. –

+0

Dường như có nhiều khả năng bạn đang gặp phải vấn đề về PgJDBC với phân tích cú pháp báo giá đô la trong quá trình tách nhiều tầng. Một ví dụ độc lập có thể biên dịch sẽ hữu ích. http://sscce.org/. Nếu bạn thêm chi tiết vào bản chỉnh sửa, vui lòng nhận xét ở đây để tôi được thông báo. –

+0

Xin chào Craig, tôi đã thêm SSCCE theo yêu cầu của bạn. Chơi có một cái nhìn.Nó tái tạo trong thiết lập chơi đơn giản nhất mà tôi có thể tạo. – Elijah

Trả lời

18

Đây là một tạo phẩm về cách Play phân tích diễn biến. Vì nó phân tích cú pháp mỗi câu lệnh trên dấu chấm phẩy, nó không thể xử lý các định nghĩa thủ tục lưu sẵn. Vấn đề đã được giải quyết trong Play 2.1 bằng cách cho phép bạn chỉ định dấu chấm phẩy được nhúng bằng cách nhân đôi chúng. Xem ví dụ https://github.com/playframework/Play20/pull/649.

Sử dụng ;; giải quyết được sự cố tương tự đối với tôi, sử dụng Play 2.1. Tôi khuyên bạn nên xác định lại sự tiến hóa của mình như sau và thử lại:

CREATE OR REPLACE FUNCTION idx(myArray anyarray, myElement anyelement) RETURNS int AS $$ 
SELECT i FROM (
    SELECT generate_series(array_lower(myArray,1),array_upper(myArray,1)) 
) g(i) 
WHERE myArray[i] = anyElement 
LIMIT 1;; $$ LANGUAGE sql IMMUTABLE;