ここニューサウスウェールズ州の極南海岸の朝です、そして私はこれで別の亀裂を取るだろうと思いました。私たちの展開環境はRDSであるため、COPYの魅力が低下することは前に述べておきました。ただし、各要素に行データが含まれる配列を渡すというアイデアは、非常に 魅力的。これは複数値のINSERTによく似ていますが、構文上の糖衣が異なります。私はPostgresの配列を少し突っ込んでいて、常に構文に戸惑っています。いくつかのトップポスターからの詳細がたくさんある本当に素晴らしいスレッドをいくつか見つけました:
そこから、動作するテスト機能があります:
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;
円を閉じるために、いくつかの入力の例を次に示します。
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[]
);
テスト結果に戻ると、これは元の複数値の挿入とほぼ同じように機能します。私が最初に投稿した他の2つの方法は、たとえば4倍遅いです。 (結果はかなり不安定ですが、常にかなり遅くなります。)しかし、私はまだ元の質問を残しています:
この注射は安全ですか?
そうでない場合は、PL/pgSQLでFOREACHループとEXECUTE...USINGまたはFORMATを使用して書き直し、インジェクションクリーニングテキスト処理/補間機能を取得する必要があると思います。誰か知っていますか?
この関数について他にもたくさん質問があります(トランザクションを管理するためのプロシージャである必要がありますか?入力anyarrayを作成するにはどうすればよいですか?返される賢明な結果は何でしょうか?)しかし、私はしなければならないと思いますそれらを彼ら自身の質問として追求してください。
助けてくれてありがとう!