6

再帰的に自分自身を呼び出すストアドFUNCTIONを作成しました。

ただし、クエリで実行すると、この恥知らずなエラーが発生します。

エラー:1424 SQLSTATE:HY000(ER_SP_NO_RECURSION)

メッセージ:再帰的に保存された関数とトリガーは許可されていません

"禁止されている"?
右。WHILEループも無効にしてみませんか?

再帰関数を有効にすることはできますか?バグレポート
を見つけましたが、回避策はありますか? Windows XP(XAMPPサーバー)でMySQL5.1.41を実行しています。

4

3 に答える 3

4

MySQL 5.1は再帰的なストアドプロシージャをサポートしていますが、再帰的な関数はサポートしていません。ドキュメントの引用:

保存された関数を再帰的にすることはできません。

ストアドプロシージャでの再帰は許可されていますが、デフォルトでは無効になっています。再帰を有効にするには、max_sp_recursion_depthサーバーシステム変数をゼロより大きい値に設定します。ストアドプロシージャの再帰により、スレッドスタックスペースの需要が増加します。の値を大きくすると、サーバーの起動時にmax_sp_recursion_depthの値を大きくして、スレッドスタックのサイズを大きくする必要がある場合があります。thread_stack

于 2010-08-21T06:02:26.173 に答える
3

MySQLはスレッドのスタックサイズを制限する必要があるため、おそらくストアドルーチンでの再帰は推奨されません。

MySQLは通常、接続ごとに1つのスレッドを使用します。数百または数千の接続が一般的です。

32ビットプラットフォームでは、1,000スレッドを実行するとアドレス空間に大きな負荷がかかるため、アドレス空間の枯渇を防ぐためにスタックを非常に小さく設定する必要があります。

もちろん、スタックオーバーフローは非常に悪いです-安全に回復することはできません。したがって、MySQLは、特に32ビットプラットフォームでスタックオーバーフローを防ぐためにこれを行うと思います。

とは言うものの、最近、実稼働MySQLサーバーに32ビットOSを使用している人は誰でも正気ではありません。

于 2010-08-21T07:34:47.363 に答える
3

問題ありません、ジェンコ。PostgreSQLの機能ほど効率的ではありませんが、MySQLのプロシージャでも可能です。

DELIMITER $$
DROP PROCEDURE IF EXISTS test.factorial_proc$$
CREATE PROCEDURE test.factorial_proc
(
   IN n   BIGINT, 
  OUT res BIGINT 
) 
BEGIN
  SET max_sp_recursion_depth=10; 
  IF n >= 2 THEN
    CALL test.factorial_proc (n-1, res);
    SELECT n * res INTO res;
  ELSE
    SELECT n INTO res;
  END IF;
END$$
DELIMITER ;

[test]> CALL test.factorial_proc (5, @res);
[test]> CALL test.factorial_proc (5, @res1);
[test]> select @res * @res1;
+--------------+
| @res * @res1 |
+--------------+
|        14400 |
+--------------+

セルゲイ・ザイツェフ。

于 2010-10-29T09:05:09.483 に答える