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

選択した行をPostgresのCSVファイルの値で更新するにはどうすればよいですか?

    コピー ファイルを一時ステージングテーブルに移動し、そこから実際のテーブルを更新します。いいね:

    CREATE TEMP TABLE tmp_x (id int, apple text, banana text); -- but see below
    
    COPY tmp_x FROM '/absolute/path/to/file' (FORMAT csv);
    
    UPDATE tbl
    SET    banana = tmp_x.banana
    FROM   tmp_x
    WHERE  tbl.id = tmp_x.id;
    
    DROP TABLE tmp_x; -- else it is dropped at end of session automatically
    

    インポートされたテーブルが正確に更新されるテーブルと一致する場合、これは便利な場合があります:

    CREATE TEMP TABLE tmp_x AS SELECT * FROM tbl LIMIT 0;
    

    制約なしで、既存のテーブルの構造に一致する空の一時テーブルを作成します。

    特権

    Postgres 10まで、SQL COPY これにはスーパーユーザー権限が必要です。
    Postgres11以降には、それを許可するための事前定義された役割(以前の「デフォルトの役割」)もいくつかあります。マニュアル:

    コピー ファイルまたはコマンドの命名は、データベーススーパーユーザーまたは pg_read_server_filesのいずれかの役割が付与されているユーザーにのみ許可されます。 、 pg_write_server_files 、または pg_execute_server_program [...]

    psql メタコマンド\ copy すべてのdbロールで機能します。マニュアル:

    フロントエンド(クライアント)コピーを実行します。これは、anSQL COPYを実行する操作です。 コマンドですが、サーバーが指定されたファイルを読み書きする代わりに、psqlはファイルを読み書きし、サーバーとローカルファイルシステムの間でデータをルーティングします。つまり、ファイルのアクセス可能性と権限はサーバーではなくローカルユーザーのものであり、SQLスーパーユーザーの権限は必要ありません。

    一時テーブルの範囲は、単一のセッションに制限されています 単一の役割であるため、上記は同じpsqlセッションで実行する必要があります。

    CREATE TEMP TABLE ...;
    \copy tmp_x FROM '/absolute/path/to/file' (FORMAT csv);
    UPDATE ...;
    

    これをbashコマンドでスクリプト化する場合は、必ずすべてをシングルでラップしてください。 psql呼び出し。いいね:

    echo 'CREATE TEMP TABLE tmp_x ...; \copy tmp_x FROM ...; UPDATE ...;' | psql
    

    通常、メタコマンド \\が必要です psqlでpsqlメタコマンドとSQLコマンドを切り替えますが、 \ copy この規則の例外です。再びマニュアル:

    \ copyには特別な解析ルールが適用されます メタコマンド。他のほとんどのメタコマンドとは異なり、行の残りの部分全体が常に \ copyの引数と見なされます。 、および変数補間もバッククォート展開も引数で実行されません。

    大きなテーブル

    インポートテーブルが大きい場合は、 temp_buffersを増やすとよいでしょう。 セッションのために一時的に(セッションの最初のもの):

    SET temp_buffers = '500MB';  -- example value
    

    一時テーブルにインデックスを追加します:

    CREATE INDEX tmp_x_id_idx ON tmp_x(id);
    

    そして、 ANALYZEを実行します 一時テーブルは自動真空/自動分析の対象外であるため、手動で。

    ANALYZE tmp_x;
    

    関連する回答:

    • IDで数百万行を削除する最良の方法
    • 異なるスキーマから一時テーブルに共通データを挿入するにはどうすればよいですか?
    • 重複するエントリを削除するにはどうすればよいですか?


    1. OracleはNumberデータ型の末尾のゼロを格納しますか?

    2. カンマ区切りの列データを追加の列に分割します

    3. PL/SQLの単体テスト

    4. SQLServerにテーブルが存在しない場合にテーブルを作成する2つの方法