web-dev-qa-db-ja.com

PostgreSQL 9.5、「キャッシュされたプランは結果タイプを変更してはなりません」エラーの取得

私はPostgreSQLで非常に奇妙な予期しない動作をしました。デバッグこの問題は、関数内に_CREATE TEMP TABLE ..._を含めたときにのみ発生し、別の方法(この場合は配列に頼った)を使用するとエラーが発生しないことがわかりました。おそらく誰かが同様のエラーを経験したか、このエラーが何に関連しているのか知っていますか?遅かれ早かれ、関数に一時テーブルを作成する必要があるかもしれません。

古いDelphi XE6プログラムをレガシーの専用データベースからPostgreSQLに移植し、TxxTableコンポーネント(独自のもの)をPostgreSQL 9.5のデータベースのコピーを指すTFDTableコンポーネント(FireDAC)に変更します。

いくつかのデータをあちこちに挿入および更新するこのplpgsql関数を作成するまで、物事はうまくいきました。私はPGConnection.ExecSQLScalar('SELECT do_stuff(:id)', FID);を介して関数を実行しました。ここで、PGConnectionはPostgreSQLへのTFDConnectionです(他の多くのテーブルを開いて正常に機能しているのと同じです)、_do_stuff_は問題の関数です。 FIDは、パラメーターとして送信するIDです。関数はPgAdminから実行する場合と同様に正常に実行されますが、接続が不安定になりますすでに開いているテーブルがその後何かを実行しようとすると(挿入/編集/移動)、次のエラーが発生します。

エラー:キャッシュされたプランは結果タイプを変更できません
ステートメント:「357STM」から50を前方にフェッチ `

FireDACは通常、カーソルを使用してテーブルとクエリを開きます。

ログ:358STMを実行:SELECT HOLDを使用して「357STM」カーソルを宣言*
FROMテーブル

TFDQueryコンポーネントを介してdo_stuff(:id)を実行すると、関数自体が失敗し(FireDACがカーソルとして実行する)、上記と同じエラーが発生します。

聞いたデバッグを引き裂いた後、エラーを回避する唯一の方法は、関数内に一時テーブルを作成しないことであることに気付きました。関数を_CREATE TEMP TABLE tbl ON COMMIT DROP AS SELECT * FROM some_table WHERE ...._またはCREATE TEMP TABLE tbl (id int, value text);として作成すると、エラーが発生しました。 _CREATE TEMP TABLE_がなければ、エラーは発生しません。

手がかりは高く評価されます!

FireDAC FDQuery。

フェッチオプションのカーソルの種類がckAutomaticに設定されました。私はそれをckDefaultに変更し、現在は機能しています。

3
Eduardo Brazil