Vấn đề không phải là cú pháp, vì cú pháp hoạt động hoàn hảo với flyway hoặc trực tiếp trong PostgreSQL CLI. Vấn đề là với Hibernate, cụ thể là với việc phân tích cú pháp tệp nhập. Cách hoạt động của Hibernate là nó thực thi từng biểu thức từ các tệp riêng lẻ, không phải toàn bộ nội dung dưới dạng một biểu thức duy nhất. Tôi đã cố gắng đặt tất cả các định nghĩa hàm trong một dòng và nó hoạt động, nhưng nó không thể đọc được. Vì vậy, tôi thấy rằng có một cấu hình cho Hibernate để cho nó biết rằng các biểu thức có thể được nhiều dòng, nhưng $$
dấu phân tách vẫn không được nhận dạng khi được sử dụng trong nhiều dòng.
Vì vậy, giải pháp là xác định lệnh với '
dấu phân tách và sau đó thoát khỏi các dấu ngoặc kép nếu cần bằng một '
bổ sung .
Giải pháp là đặt spring.jpa.properties.hibernate.hbm2ddl.import_files_sql_extractor
để sử dụng org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor
. MultipleLinesSqlCommandExtractor trích xuất biểu thức SQL từ nhiều dòng và dừng khi có dấu chấm phẩy. Đó là phần cuối của biểu thức. Bằng cách gói phần thân của hàm trong chuỗi dấu ngoặc kép, Hibernate sẽ coi gói đó là một dòng duy nhất.
data.sql
CREATE OR REPLACE FUNCTION insert_timeout_configuration() RETURNS bigint AS '
DECLARE created_id bigint;
BEGIN
INSERT INTO timeout_configuration (id, version, timeout)
VALUES (nextval(''my_sequence''), 0, 300)
RETURNING id INTO created_id;
return created_id;
END;
' language plpgsql;
CREATE OR REPLACE FUNCTION insert_url_configuration() RETURNS bigint AS '
DECLARE created_id bigint;
BEGIN
INSERT INTO url_configuration (id, version, my_url)
VALUES (nextval(''my_sequence''), 0,''http://localhost:8080/'')
RETURNING id INTO created_id;
return created_id;
END;
' language plpgsql;
DO '
INSERT INTO global_configuration(id, version, name, timeout_configuration_id, url_configuration_id)
VALUES (nextval(''my_sequence''), 0, ''My global config'', insert_timeout_configuration(), insert_url_configuration());
-- do some other code
END
';
drop function insert_timeout_configuration();
drop function insert_url_configuration();
Tôi phải luôn ghi nhớ để thoát khỏi các dấu ngoặc đơn trong biểu thức, nhưng bây giờ tôi có thể có một tệp hạt giống mà con người có thể đọc được.