Ini pagi di sini di Pantai Selatan Jauh NSW, dan saya pikir saya akan mencoba lagi. Saya seharusnya menyebutkan sebelumnya bahwa lingkungan penerapan kami adalah RDS, yang membuat COPY kurang menarik. Tetapi gagasan untuk melewatkan larik di mana setiap elemen menyertakan data baris sangat menarik. Ini seperti INSERT multi-nilai, tetapi dengan gula sintaksis yang berbeda. Saya telah sedikit menyodok array di Postgres, dan selalu bingung dengan sintaksnya. Saya menemukan beberapa utas yang sangat bagus dengan banyak detail dari beberapa poster teratas untuk dipelajari:
https://dba.stackexchange .com/questions/224785/pass-array-of-mixed-type-into-stored-function
Dari sana, saya mendapatkan fungsi pengujian yang berfungsi:
DROP FUNCTION IF EXISTS data.item_insert_array (item[]);
CREATE OR REPLACE FUNCTION data.item_insert_array (data_in item[])
RETURNS int
AS $$
INSERT INTO item (
id,
marked_for_deletion,
name_)
SELECT
d.id,
d.marked_for_deletion,
d.name_
FROM unnest(data_in) d
ON CONFLICT(id) DO UPDATE SET
marked_for_deletion = EXCLUDED.marked_for_deletion,
name_ = EXCLUDED.name_;
SELECT cardinality(data_in); -- array_length() doesn't work. ¯\_(ツ)_/¯
$$ LANGUAGE sql;
ALTER FUNCTION data.item_insert_array(item[]) OWNER TO user_bender;
Untuk menutup lingkaran, berikut ini contoh beberapa masukan:
select * from item_insert_array(
array[
('2f888809-2777-524b-abb7-13df413440f5',true,'Salad fork'),
('f2924dda-8e63-264b-be55-2f366d9c3caa',false,'Melon baller'),
('d9ecd18d-34fd-5548-90ea-0183a72de849',true,'Fondue fork')
]::item[]
);
Kembali ke hasil pengujian saya, ini bekerja secara kasar sebaik sisipan multi-nilai asli saya. Dua metode lain yang saya posting awalnya, katakanlah, 4x lebih lambat. (Hasilnya cukup tidak menentu, tetapi selalu jauh lebih lambat.) Tapi saya masih memiliki pertanyaan awal saya:
Apakah suntikan ini aman?
Jika tidak, saya rasa saya perlu menulis ulang dalam PL/pgSQL dengan perulangan FOREACH dan EXECUTE...USING atau FORMAT untuk mendapatkan fitur pemrosesan teks/interpolasi pembersih injeksi di sana. Ada yang tahu?
Saya memiliki banyak pertanyaan lain tentang fungsi ini (Haruskah ini menjadi prosedur agar saya dapat mengelola transaksi? Bagaimana cara membuat array input? Apa hasil yang masuk akal untuk dikembalikan?) Tapi saya pikir saya harus melakukannya kejar itu sebagai pertanyaan mereka sendiri.
Terima kasih atas bantuannya!