MySQLストアドルーチンの動的SQL


13

ストアドルーチンとトリガーの制限に従って、動的SQLは使用できません(バージョン5.0.13以降のストアドプロシージャの制限は解除されました)。この制限が設定されているのはなぜですか?そして、なぜそれを手順のために持ち上げますが、機能やトリガーではありませんか?

回答:


8

質問を聞くだけで、次の2つの側面を考えることができます。

側面#1:関数は決定的であることになっています

その場合、これは、関数が特定のパラメーターセットに対して同じ戻りデータを一貫して提示する必要があることを意味します。関数を呼び出すときは重要ではありません。

ここで、関数内の静的SQLに基づいて1日の異なる時間にデータを収集するため、異なる答えを生成する関数を想像してください。ある意味では、同じパラメーターのセットを指定して、同じテーブルと列のセットを毎回クエリする場合、それは決定的と見なすことができます。

ダイナミックSQLを介して関数の基礎となるテーブルを変更できるとしたらどうでしょうか?DETERMINISTIC関数の定義に違反しています。

MySQLがこのオプションを/etc/my.cnfに追加したことに注意してください。

log-bin-trust-function-creators

これは言い過ぎかもしれませんが、これにより、関数がDETERMINISTICプロパティを厳密に強制することなく、バイナリログにデータを書き込むことができるようになります。

側面#2:トリガーはロールバックできる必要があります

  • 関数とまったく同じ動作をするトリガーを想像してから、ダイナミックSQLをミックスに導入できますか?
  • トリガーが意図されたベーステーブルにMVCCを適用した後、ダイナミックSQLに対してMVCC(Multiversion Concurrecy Control)を適用しようとすることを想像できますか?

基本的には、MVCCだけで二次的に(指数的にも)増加するデータがあります。非決定的である可能性のあるトリガーを使用してSQLのロールバックを管理するプロセスは、控えめに言っても非常に複雑です。

これらの2つの側面に照らして、MySQL開発者はこれらのことを考え、制限を課すことですぐにそれらを却下したと確信しています。

それでは、なぜ手順の制限を解除するのですか?簡単に言えば、決定的なプロパティやロールバックに関する懸念はありません。


3
他のDBMSがトリガーでMVCCと動的SQLを非常にうまくサポートできる場合、それほど「複雑ではない」ことはできません。
a_horse_with_no_name

1
実際、@ a_horse_with_no_name、あなたは正しいです。OracleとPostgreSQLについては、不格好な複雑さがコーディングされています。あなたのコメントのために+1。MySQLには複数のストレージエンジンを処理するハンディキャップがあるため、ロールバックと決定論ではストレージエンジン操作の重複が必要になる場合があります。それは少し怖いです。たぶん誰かが「不気味に複雑」をInnoDBに完全にプッシュする勇気を持っているでしょう。さらに望ましいのは、同じクエリ内でストレージエンジンを混在させないように、ストレージエンジン固有のトリガー実装を作成することです。
-RolandoMySQLDBA

5

これは素晴らしい質問ですが、答えはわかりません。これは内部チームに行く必要があると思いますが、彼らがこのサイトに大きくなることを知りません。それまでの間、私はあなたがいくつかの答えを推測するのを手伝うことができます。

手始めに私はこれを見ます:

トリガーキャッシュは、基になるオブジェクトのメタデータがいつ変更されたかを検出しません。トリガーがテーブルを使用し、トリガーがキャッシュにロードされてからテーブルが変更された場合、トリガーは古いメタデータを使用して動作します。

それはそれが何か関係があると私に思わせます。メタデータを監視していなければ、SQLを再コンパイルすることはありません。これは、エンジンの問題であることを意味します。

同様に、このブロックを読んだとき、私は同じこと(エンジン)を考えています:

サーバースレッド間の相互作用の問題を防ぐために、クライアントがステートメントを発行すると、サーバーはステートメントの実行に使用可能なルーチンとトリガーのスナップショットを使用します。つまり、サーバーは、ステートメントの実行中に使用できるプロシージャ、関数、およびトリガーのリストを計算し、それらをロードしてから、ステートメントの実行に進みます。これは、ステートメントが実行されている間、他のスレッドによって実行されるルーチンへの変更が表示されないことを意味します。

結局のところ、なぜ彼らがそれを許可しないのかは完全にはわかりませんが、推測できます。私はあなたをもっと助けることができないことを残念に思う、私はこれをもう少し停止することに心を開いている。プライベートベータを終了したら、アクティブなMySQL開発者を期待するのが最善です;)


1

これは主にセキュリティによるものです。プロシージャの例外は、プロシージャ内の動的SQLに実行中のユーザーのセキュリティコンテキストを割り当てることができるためです。これは、エンジンがが実行されるかを知らなくても、ユーザーが参照オブジェクトへのアクセスを許可されていることを確認できることを意味します。

それを超えて、許されるならば、あなたは何が起こるかというugい問題を提起することができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.