Masalahnya bukan pada sintaks, karena sintaks bekerja sempurna dengan jalur terbang atau langsung di PostgreSQL CLI. Masalahnya adalah dengan Hibernate, khususnya dengan mem-parsing file impor. Cara kerja Hibernate adalah ia mengeksekusi setiap ekspresi dari file satu per satu, bukan seluruh konten sebagai ekspresi tunggal. Saya mencoba meletakkan semua definisi fungsi dalam satu baris dan berhasil, tetapi tidak dapat dibaca. Jadi saya menemukan bahwa ada konfigurasi untuk Hibernate untuk memberitahunya bahwa ekspresi dapat multi-baris, tetapi $$
pembatas masih belum dikenali saat digunakan di multi-line.
Jadi solusinya adalah mendefinisikan perintah dengan '
pembatas dan kemudian keluar dari tanda kutip tunggal jika diperlukan dengan tambahan '
.
Solusinya adalah dengan mengatur spring.jpa.properties.hibernate.hbm2ddl.import_files_sql_extractor
untuk menggunakan org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor
. MultipleLinesSqlCommandExtractor mengekstrak ekspresi SQL dari beberapa baris, dan berhenti saat ada titik koma. Itu adalah akhir dari ekspresi. Dengan membungkus tubuh fungsi dalam string tanda kutip tunggal, Hibernate akan memperlakukan pembungkus itu sebagai satu baris.
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();
Saya harus selalu ingat untuk menghindari tanda kutip tunggal dalam ekspresi, tetapi sekarang saya dapat memiliki file benih yang lebih dapat dibaca manusia.