これには動的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%');
-
関数をより実用的にするために、コメントで説明されているように情報を返します。 結果ステータスの取得> マニュアルのplpgsqlにあります。
-
変数
_sql
を使用します クエリ文字列を保持するため、見つかった列の数を収集できます(col_ct
)同じクエリで。 -
オブジェクト識別子タイプ
regclass
これは、テーブル名のSQLインジェクションを自動的に回避する(および非標準名をサニタイズする)ための最も効率的な方法でもあります。 スキーマ修飾テーブル名を使用できます あいまいさを避けるため。データベースに複数のスキーマがある場合は、そうすることをお勧めします。この関連する質問の詳細:
PostgreSQL関数パラメーターとしてのテーブル名