あなたはそのためのDO
文またはplpgsqlが関数内のシステムカタログから動的にUPDATE
コマンドを構築することができます。これは、組み立てと自動的にフォームのクエリを実行し
CREATE OR REPLACE FUNCTION f_global_replace(_tbl regclass
, _old text
, _new text
, OUT updated_rows int) AS
$func$
DECLARE
-- basic char types, possibly extend with citext, domains or custom types:
_typ CONSTANT regtype[] := '{text, bpchar, varchar}';
_sql text;
BEGIN
SELECT INTO _sql -- build command
format('UPDATE %s SET %s WHERE $1 IN (%s)'
, _tbl
, string_agg(format('%1$s = CASE WHEN %1$s = $1 THEN $2 ELSE %1$s END', col), ', ')
, string_agg(col, ','))
FROM (
SELECT quote_ident(attname) AS col -- escape names, prevent SQL injection!
FROM pg_attribute
WHERE attrelid = _tbl -- valid, visible, legal table name
AND attnum >= 1 -- exclude tableoid & friends
AND NOT attisdropped -- exclude dropped columns
AND atttypid = ANY(_typ) -- only character types
ORDER BY attnum
) sub;
-- RAISE NOTICE '%', _sql; -- debug
IF _sql IS NULL THEN
updated_rows := 0; -- nothing to update
ELSE
EXECUTE _sql USING _old, _new;
GET DIAGNOSTICS updated_rows = ROW_COUNT; -- Report number of affected rows
END IF;
END
$func$ LANGUAGE plpgsql;
:
UPDATE table1 SET field1 = CASE WHEN field1 = $1 THEN $2 ELSE field1 END , field2 = CASE WHEN field2 = $1 THEN $2 ELSE field2 END , field3 = CASE WHEN field3 = $1 THEN $2 ELSE field3 END WHERE $1 IN (field1,field2,field3);
注意!この関数は、すべての文字型列を更新します。期待どおりに動作することを確認してください。安全のために私は明示的なトランザクション内でそれを実行することをお勧めしてのみチェックした後にコミット:
BEGIN;
SELECT * FROM f_global_replace('table1'::regclass, 'n/a', 'NA');
TABLE table1; -- all good?
COMMIT; -- then commit; else ROLLBACK;
より多くの情報とリンクとの関連答え:
をありがとう助けのために:) –
@ニチンゴール:それがあなたの質問に答えるなら、[それを受け入れることを検討する](http://meta.stackexchange.com/questions/5234/ho応答受付作業/ 5235#5235)。 –