web-dev-qa-db-ja.com

変異テーブルエラーの原因と解決策は何ですか?

変更テーブルエラーの原因は、設計上の欠陥または問題のあるクエリです。

古いクエリが最近本番環境に導入され、変更テーブルエラーがスローされました。 DBAが問題を解決しましたが、方法はわかりません。

変更テーブルエラーの正確な原因と、DBAはどのように問題を修正したでしょうか。

12
parmanand

変異テーブルエラーの最も可能性の高い原因は、トリガーの誤用です。これが典型的な例です:

  1. テーブルAに行を挿入します
  2. テーブルAのトリガー(行ごと)は、テーブルAでクエリを実行します。たとえば、サマリー列を計算します。
  3. OracleがORA-04091をスローします:テーブルAが変化しているため、トリガー/関数で認識されない可能性があります

これは予期された通常の動作であり、Oracleは次のことを保証するため、ユーザーを保護します。

  • (i)各ステートメントがアトミックであること(つまり、失敗または完全に成功すること)
  • (ii)各ステートメントがデータの一貫したビューを見る

ほとんどの場合、この種のトリガーを作成すると、クエリ(2)に(1)に挿入された行が表示されることが予想されます。これは、更新がまだ完了していないため(挿入する行がさらにある可能性があるため)、上記の両方の点と矛盾します。

Oraclecouldは、ある時点の直前と一致する結果を返します。ステートメントの始まりですが、このロジックを実装しようとした私が見たほとんどの例から、人々は複数行のステートメントを一連のステップの連続と見なし、ステートメント[2]が前のステップによる変更を確認することを期待しています。 Oracleは期待される結果を返すことができないため、エラーをスローします。

さらに読むために: Ask Tomの "mutating table"

変異テーブルエラーの原因がトリガーであると思われる場合、エラーを回避する1つの方法は、ロジックをトリガーからプロシージャに移動することです。

17
Vincent Malgrat

mutating table は、ステートメントがトリガーを起動し、そのトリガーがトリガーを引き起こしたテーブルを参照するときに発生します。このような問題を回避する最善の方法は、トリガーを使用しないことですが、DBAが時間をかけてそれを行わなかったのではないかと思います。彼は次のいずれかを行った可能性があります。

9
Leigh Riffel