2016-08-04 8 views
-3

更新方法ALL PostgreSQLのテーブルの列?一度に1列ずつ行うのではなく、この表を考えると
テーブルのすべての列で「n/a」を「NA」に置き換えます。

Table1 
Field1 | Field 2 | Field 3 
123 | 987  | n/a 
456 | n/a  | 101 
n/a | abcdef | n/a 

結果は次のようになります。

Table1 
Field1 | Field 2 | Field 3 
123 | 987  | NA 
456 | NA  | 101 
NA  | abcdef | NA 

私は単一 SQLクエリを探しています。

答えて

0

あなたはそのための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; 

より多くの情報とリンクとの関連答え:

+0

をありがとう助けのために:) –

+0

@ニチンゴール:それがあなたの質問に答えるなら、[それを受け入れることを検討する](http://meta.stackexchange.com/questions/5234/ho応答受付作業/ 5235#5235)。 –

関連する問題