カウントによって巨大なテーブルを新しいテーブルにロールアップしています。ここで、すべての空の文字列をに変更し、NULL
いくつかの列も型キャストします。いくつかの投稿を読みましたが、クエリが見つかりませんでした。これにより、複数のステートメントを使用せずに、1つのクエリですべての列にまたがって実行できます。
すべての列を反復処理して、セルをnullの空の文字列に置き換えることが可能かどうかを教えてください。
カウントによって巨大なテーブルを新しいテーブルにロールアップしています。ここで、すべての空の文字列をに変更し、NULL
いくつかの列も型キャストします。いくつかの投稿を読みましたが、クエリが見つかりませんでした。これにより、複数のステートメントを使用せずに、1つのクエリですべての列にまたがって実行できます。
すべての列を反復処理して、セルをnullの空の文字列に置き換えることが可能かどうかを教えてください。
私の知る限り、テーブルのすべての列で空の文字列を置き換える組み込み関数はありません。それを処理するためにplpgsql 関数を書くことができます。
次の関数は、指定されたテーブルのすべての基本的な文字型列の空の文字列を に置き換えますNULL
。integer
その後、残りの文字列が有効な数値リテラルである場合にキャストできます。
CREATE OR REPLACE FUNCTION f_empty_text_to_null(_tbl regclass, OUT updated_rows int)
LANGUAGE plpgsql AS
$func$
DECLARE
_typ CONSTANT regtype[] := '{text, bpchar, varchar}'; -- ARRAY of all basic character types
_sql text;
BEGIN
SELECT INTO _sql -- build SQL command
'UPDATE ' || _tbl
|| E'\nSET ' || string_agg(format('%1$s = NULLIF(%1$s, '''')', col), E'\n ,')
|| E'\nWHERE ' || string_agg(col || ' = ''''', ' OR ')
FROM (
SELECT quote_ident(attname) AS col
FROM pg_attribute
WHERE attrelid = _tbl -- valid, visible, legal table name
AND attnum >= 1 -- exclude tableoid & friends
AND NOT attisdropped -- exclude dropped columns
AND NOT attnotnull -- exclude columns defined NOT NULL!
AND atttypid = ANY(_typ) -- only character types
ORDER BY attnum
) sub;
-- RAISE NOTICE '%', _sql; -- test?
-- Execute
IF _sql IS NULL THEN
updated_rows := 0; -- nothing to update
ELSE
EXECUTE _sql;
GET DIAGNOSTICS updated_rows = ROW_COUNT; -- Report number of affected rows
END IF;
END
$func$;
電話:
SELECT f_empty2null('mytable');
SELECT f_empty2null('myschema.mytable');
列名も取得するにはupdated_rows
:
SELECT * FROM f_empty2null('mytable');
テーブル名は有効で表示可能である必要があり、呼び出し元のユーザーは必要なすべての権限を持っている必要があります。これらの条件のいずれかが満たされない場合、関数は何もしません。つまり、何も破棄できません。それを確認するために、オブジェクト識別子の型regclass
にキャストします。
テーブル名はそのまま ( 'mytable'
) で指定でき、その後 がsearch_path
決定します。または、特定のスキーマを選択するスキーマ修飾 ( 'myschema.mytable'
)。
システム カタログを照会して、テーブルのすべての ( character-type ) 列を取得します。提供された関数は、次の基本的な文字タイプを使用します: text
, bpchar
, varchar
, "char"
. 関連する列のみが処理されます。
quote_ident()
またはを使用format()
して列名をサニタイズし、SQLi から保護します。
更新されたバージョンでは、基本的な SQL 集計関数を使用して、string_agg()
ループなしでコマンド文字列を構築します。これは、よりシンプルで高速です。そしてよりエレガントに。:)
で動的 SQLEXECUTE
を使用する必要があります。
更新されたバージョンでは、定義された列が除外され、単一のステートメントNOT NULL
で各行が 1 回だけ更新されます。
最新バージョンの PostgreSQL で動作するはずです。Postgres 9.1、9.3、9.5、および 13 でテスト済み。