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

特定の文字列で始まる複数の列を更新します

    これには動的SQLが必要です。したがって、SQLインジェクションの可能性に対処する準備をする必要があります。

    基本クエリ

    必要なDMLコマンドを生成するための基本的なクエリは次のようになります。

    SELECT format('UPDATE tbl SET (%s) = (%s)'
                   ,string_agg (quote_ident(attname), ', ')
                   ,string_agg ('NULL', ', ')
                 )
    FROM   pg_attribute
    WHERE  attrelid = 'tbl'::regclass
    AND    NOT attisdropped 
    AND    attnum > 0
    AND    attname ~~ 'foo_%';
    

    返品:

    UPDATE tbl SET (foo_a, foo_b, foo_c) = (NULL, NULL, NULL);
    
    • "列リスト構文 "のUPDATE コードを短くしてタスクを簡素化するため。

    • システムカタログにクエリを実行します 情報スキーマ の代わりに 後者は標準化されており、メジャーバージョン間での移植が保証されていますが、速度が遅く、扱いにくいこともあります。長所と短所があります。これについては、SOで何度か説明しました。詳細については、キーワードを検索してください。

    • quote_ident() 列名はSQLインジェクションを防ぎ、すべてにも必要です。 非標準の列名。

    • あなたはPostgresのバージョンについて言及することを怠りました。集計関数 string_agg() 9.0以上が必要です。

    PL/pgSQL関数による完全自動化

    CREATE OR REPLACE FUNCTION f_update_cols(_tbl regclass, _col_pattern text
                                            , OUT row_ct int, OUT col_ct int)
      RETURNS record AS
    $func$
    DECLARE
       _sql text;
    BEGIN
       SELECT format('UPDATE tbl SET (%s) = (%s)'
                     ,string_agg (quote_ident(attname), ', ')
                     ,string_agg ('NULL', ', ')
                    )
             ,count(*)::int
       INTO   _sql, col_ct
       FROM   pg_attribute
       WHERE  attrelid = _tbl
       AND    NOT attisdropped         -- no dropped columns
       AND    attnum > 0               -- no system columns
       AND    attname ~~ _col_pattern; -- only columns matching pattern
    
       -- RAISE NOTICE '%', _sql;      -- output generated SQL for debugging
       EXECUTE _sql;
    
       GET DIAGNOSTICS row_ct = ROW_COUNT;
    END
    $func$  LANGUAGE plpgsql;
    
    COMMENT ON FUNCTION f_update_cols(regclass, text)
     IS 'Updates all columns of table _tbl ($1)
    that match _col_pattern ($2) in a LIKE expression.
    Returns the count of columns (col_ct) and rows (row_ct) affected.';
    

    電話:

    SELECT * FROM f_update_cols('myschema.tbl', 'foo%');
    

    ->SQLfiddleデモ



    1. [テンプレート]、[エンコーディング]、[所有者]のバッチファイルと.sqlファイルを使用してPostgresデータベースを作成します

    2. Laravel / Eloquent:ネストされたWhereHas

    3. PL / SQL:スクリプトの実行を完全に停止する命令はありますか?

    4. 存在しないものを選択してください