2016-11-13 11 views
1

Postgresテーブルmy_tableでは、すべての変数の空の文字列('')をすべてnullに設定します。私は実行行で失敗する以下のdo-blockを持っています。Postrgres plpgsqlを使用してテキスト変数に格納された動的SQLクエリを実行する

私はかなりplpgsqlに新しくなっており、その理由を理解していません。 qに保存されているコマンドを正しく実行するにはどうすればよいですか?

do language plpgsql 
$$ 
DECLARE 
    r record; 
    q text; 
BEGIN 
    for r in 
     select table_name, column_name 
     from information_schema.columns t 
     where t.table_name = 'my_table' 
    loop 
    q := format('UPDATE %s SET %s = NULL WHERE %s = '''';', 
        r.table_name, r.column_name, r.column_name); 
    raise notice 'cleaning column: %', q; 
    execute q; -- this line fails 
    end loop; 
END; 
$$; 

ps。より良いコードのための任意の他のヒントは、あなたがテキストに整数idを比較することはできませんとしてクエリ

UPDATE id SET id = NULL WHERE id = '' 

は、エラーが発生します非テキスト列(例えば整数id)について

答えて

2

をも:)歓迎されています。あなたが唯一のテキスト列、例えばのための更新クエリを実行することができます別の方法として

... 
q := format('UPDATE %I SET %I = NULL WHERE %I::text = '''';', 
      r.table_name, r.column_name, r.column_name); 
... 

... 
    select table_name, column_name 
    from information_schema.columns t 
    where t.table_name = 'my_table' 
    and data_type in ('text', 'character varying') 
... 
+1

をこの答えは延長すべき:

使用すると、テキストにキャスト。まず、列はNOT NULLと定義され、エラーが発生します。第二に、この関数は書かれているようにSQLインジェクションの問題を抱えています。悪意のあるテーブルや列名を持つ関数を定義するだけです。 –

+0

ありがとう、@klin、あなたは私がエラーを掲示しなければ問題を理解しました。ニース。 One ** Add-on **: 'raise notice'はループ全体が終了するまで何も表示しません。毎回のループサイクル後に印刷する方法はありますか? –

+0

@MarkHeckmann - 通知はすぐに呼び出されますが、クライアントが受け取る方法はこのクライアントによって異なります。たとえば、** psql **の通知は非同期で表示されます。 – klin

関連する問題