sql >> データベース >  >> RDS >> PostgreSQL

インジェクションセーフなPostgresの一括挿入/更新。おそらく配列を取る関数ですか?

    ここニューサウスウェールズ州の極南海岸の朝です、そして私はこれで別の亀裂を取るだろうと思いました。私たちの展開環境はRDSであるため、COPYの魅力が低下することは前に述べておきました。ただし、各要素に行データが含まれる配列を渡すというアイデアは、非常に 魅力的。これは複数値のINSERTによく似ていますが、構文上の糖衣が異なります。私はPostgresの配列を少し突っ込んでいて、常に構文に戸惑っています。いくつかのトップポスターからの詳細がたくさんある本当に素晴らしいスレッドをいくつか見つけました:

    https://dba.stackexchange .com / questions / 224785 / pass-array-of-mixed-type-in​​to-stored-function

    https ://dba.stackexchange.com/questions/131505/use-array-of-composite-type-as-function-parameter-and-access-it

    https://dba.stackexchange.com/questions/225176/how-to-pass-an-array-to-a-plpgsql-function-with-variadic-parameter/

    そこから、動作するテスト機能があります:

    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を作成するにはどうすればよいですか?返される賢明な結果は何でしょうか?)しかし、私はしなければならないと思いますそれらを彼ら自身の質問として追求してください。

    助けてくれてありがとう!




    1. データをmysqlテーブルにロードするが、空白行を無視する方法

    2. NHibernateを使用して同じASP.NETアプリでOracleとSQLServerの両方をサポートするための推奨事項

    3. mySQLのSQLServer関数SCOPE_IDENTITY()に相当しますか?

    4. Java経由で画像を挿入する際のPostgresエンコーディングUTF8エラー