6

Tôi đã viết một FUNCTION được lưu trữ tự gọi, đệ quy.MySQL không hỗ trợ chức năng đệ quy? tại sao? Kể từ khi?

Tuy nhiên khi tôi chạy nó trong một truy vấn tôi nhận được lỗi không biết xấu hổ này:

Error: 1424 SQLSTATE: HY000 (ER_SP_NO_RECURSION)

Message: Recursive stored functions and triggers are not allowed.

"Không cho phép"?
Phải. Tại sao chúng ta không chỉ vô hiệu WHILE vòng lặp, trong khi chúng ta đang ở đó?

Tôi có thể bật chức năng đệ quy theo bất kỳ cách nào không?
Tôi tìm thấy một bug report, nhưng có cách giải quyết nào không?
Tôi đang chạy MySQL 5.1.41 trên Windows XP (Máy chủ XAMPP).

+2

Cơ sở dữ liệu để truy xuất dữ liệu chứ không phải để lập trình. Có một số lý do bạn đang cố gắng thực hiện logic phức tạp, khó dự đoán hoặc tối ưu hóa trong một quy trình được lưu trữ thay vì trong ứng dụng của bạn không? – Borealid

+0

http://stackoverflow.com/questions/3438111/mysql-stored-procedure-that-calles-itself-recursively – Novemberland

+1

Lỗi không biết xấu hổ! Có một cách bạn có thể kích hoạt chức năng đệ quy; bạn phải sửa đổi mã MySQL để làm cho chúng hoạt động. –

Trả lời

3

Không sao, Jenco. Không hiệu quả như các hàm PostgreSQL, nhưng cũng có thể trong các thủ tục 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 | 
+--------------+ 

Sergei Zaytsev.

4

MySQL 5.1 hỗ trợ các thủ tục được lưu trữ đệ quy, nhưng không hỗ trợ các hàm đệ quy. Trích dẫn số docs:

Stored functions cannot be recursive.

Recursion in stored procedures is permitted but disabled by default. To enable recursion, set the max_sp_recursion_depth server system variable to a value greater than zero. Stored procedure recursion increases the demand on thread stack space. If you increase the value of max_sp_recursion_depth , it may be necessary to increase thread stack size by increasing the value of thread_stack at server startup.

+0

Tôi vẫn muốn một giải pháp bằng cách sử dụng FUNCTIONS vì tôi có một phương thức đệ quy tự gọi các giá trị trả về mong đợi. Nếu tôi sử dụng một THỦ TỤC không có cách nào tôi sẽ có thể làm điều đó ... tôi sẽ? –

+1

@Jenko: Bất cứ điều gì có thể được thực hiện bằng cách sử dụng đệ quy có thể được viết lại bằng cách sử dụng iteration: http://stackoverflow.com/questions/931762/can-every-recursion-be-converted-into-iteration –

3

Có lẽ đệ quy trong thói quen được lưu trữ không được khuyến khích vì MySQL cần giới hạn kích thước ngăn xếp của chủ đề.

MySQL thường sử dụng một chuỗi cho mỗi kết nối. 100 hoặc 1000 kết nối là phổ biến.

Trên nền tảng 32 bit, có áp lực không gian địa chỉ quan trọng khi chạy 1.000 luồng, vì vậy ngăn xếp cần phải được đặt rất nhỏ để tránh cạn kiệt không gian địa chỉ.

Ngăn tràn ngăn xếp, tất nhiên, rất tệ - không thể khôi phục được từ an toàn. Vì vậy, tôi nghĩ rằng MySQL làm điều này để ngăn chặn tràn ngăn xếp, đặc biệt là trên nền tảng 32-bit.

Điều đó nói rằng, bất kỳ ai sử dụng hệ điều hành 32 bit cho máy chủ MySQL sản xuất ngày nay đều mất trí.

+0

"Stack tràn là, tất nhiên , rất tệ - nó không thể được phục hồi một cách an toàn "điều này là hoàn toàn sai. TẤT CẢ các ngôn ngữ lập trình bậc cao hợp lý quản lý để phục hồi an toàn từ tràn ngăn xếp, chẳng hạn như Java, Perl, Python, ... – intgr