Postgresデータベースにデータをインポートした後、ODBCソースから入ってくるデータの一部を正規化する関数を実行します。1つのフィールドは日付ですが、varcharとして入力され、一部の行ではnullであるため、日付型に変換しようとすると失敗します。データは表示にのみ使用されるため、それほど重要ではないことに気付きましたが、有用な形式である必要があるため、次のSQLを見つけました。
UPDATE "MyTable" SET "VisitDate" = to_char( DATE("VisitDate"), 'DD Mon YYYY' ) WHERE "VisitDate" <> '';
これは、SQLブラウザーで直接実行すると機能しますが、関数を実行すると次のように表示されます。
ERROR: table row type and query-specified row type do not match
DETAIL: Table has type character varying at ordinal position 6, but query expects text.
私の知る限り、これはto_char()
関数がテキストを返すためですが、フィールドはvarcharであるため(コンテンツを指定すると、論理的になります)、次のことができると思いました。
ALTER TABLE "MyTable" ALTER "VisitDate" TYPE "text";
UPDATE "MyTable" SET "VisitDate" = to_char( DATE("VisitDate"), 'DD Mon YYYY' ) WHERE "VisitDate" <> '';
ALTER TABLE "MyTable" ALTER "VisitDate" TYPE varchar(12);
もちろん、それは関数では機能しません。なぜなら、私が理解しているように、Postgresはすべてを単一のトランザクションで実行するため、UPDATEの前にALTER命令が発生しないため、同じエラーが発生するからです。
使用しようとするvarchar( to_char( ...etc ))
と、varchar関数の内容について文句を言うだけです。
以下のコメントに続いて、関数にその行だけを入れてみましたが、成功しました。関数にすべてのテーブル変更ステートメントがある場合は成功し、両方がある場合は失敗します。関数の基本的な形式は次のとおりです。
CREATE OR REPLACE FUNCTION at_ebc_alterscorescolumns() RETURNS void AS
$BODY$
ALTER TABLE "MyTable" ALTER "Postcode" TYPE varchar(10);
UPDATE "MyTable" SET "VisitDate" = to_char( DATE("VisitDate"), 'DD Mon YYYY' ) WHERE "VisitDate" <> '';
$BODY$
LANGUAGE sql VOLATILE
COST 100;
これは、単一の関数でテーブルを変更したりデータを変更したりすることができないという単純なケースではないかと思います。
私の質問は、このエラーを発生させずにフィールドのフォーマットを変更するにはどうすればよいですか?