Làm cách nào để lặp trong thủ tục lưu sẵn MySQL?

Nhận toàn quyền truy cập vào Lập trình thủ tục lưu trữ MySQL và hơn 60.000 tiêu đề khác, với bản dùng thử miễn phí 10 ngày của O'Reilly

Ngoài ra còn có các sự kiện trực tuyến trực tiếp, nội dung tương tác, tài liệu chuẩn bị chứng nhận, v.v.

Trong phần này, chúng tôi kiểm tra các câu lệnh mà ngôn ngữ chương trình được lưu trữ MySQL cung cấp cho các lệnh xử lý lặp đi lặp lại (lặp đi lặp lại). Có nhiều lý do tại sao một chương trình có thể cần lặp lại

  • Một chương trình hỗ trợ giao diện người dùng có thể chạy một vòng lặp chính chờ và sau đó xử lý các lần nhấn phím của người dùng (tuy nhiên, điều này không áp dụng cho các chương trình được lưu trữ)

  • Nhiều thuật toán toán học chỉ có thể được thực hiện bằng các vòng lặp trong chương trình máy tính

  • Khi xử lý một tệp, một chương trình có thể lặp qua từng bản ghi trong tệp và thực hiện các phép tính

  • Một chương trình cơ sở dữ liệu có thể lặp qua các hàng được trả về bởi câu lệnh

    Infinite_loop: LOOP
        SELECT 'Welcome to my infinite 
     loop from hell!!';
    END LOOP inifinite_loop;
    3

Khá rõ ràng rằng đây là trường hợp cuối cùng—xử lý các hàng được trả về bởi câu lệnh

Infinite_loop: LOOP
    SELECT 'Welcome to my infinite 
 loop from hell!!';
END LOOP inifinite_loop;
3—sẽ là lý do phổ biến nhất dẫn đến vòng lặp trong các chương trình được lưu trữ trong MySQL và chúng tôi sẽ xem xét chủ đề này rất nhiều trong Chương 5. Trong chương này, chúng ta xem xét các lệnh lặp ở dạng tổng quát

Cấu trúc vòng lặp đơn giản nhất có thể là câu lệnh

Infinite_loop: LOOP
    SELECT 'Welcome to my infinite 
 loop from hell!!';
END LOOP inifinite_loop;
5. Cú pháp của câu lệnh này như sau

    [label:] LOOP
        statements
    END LOOP 
 [label];

Các câu lệnh giữa câu lệnh

Infinite_loop: LOOP
    SELECT 'Welcome to my infinite 
 loop from hell!!';
END LOOP inifinite_loop;
5 và câu lệnh
Infinite_loop: LOOP
    SELECT 'Welcome to my infinite 
 loop from hell!!';
END LOOP inifinite_loop;
7 sẽ được lặp lại vô thời hạn, cho đến khi câu lệnh
Infinite_loop: LOOP
    SELECT 'Welcome to my infinite 
 loop from hell!!';
END LOOP inifinite_loop;
5 kết thúc. Bạn có thể chấm dứt
Infinite_loop: LOOP
    SELECT 'Welcome to my infinite 
 loop from hell!!';
END LOOP inifinite_loop;
5 bằng cách sử dụng câu lệnh
    LEAVE label;
0 mà chúng tôi sẽ mô tả ngay sau đây

Bạn có thể cung cấp nhãn cho vòng lặp, có cùng cú pháp với cú pháp chúng ta có thể thêm vào khối

    LEAVE label;
1. Nhãn có thể giúp bạn xác định câu lệnh
Infinite_loop: LOOP
    SELECT 'Welcome to my infinite 
 loop from hell!!';
END LOOP inifinite_loop;
7 tương ứng với một câu lệnh
Infinite_loop: LOOP
    SELECT 'Welcome to my infinite 
 loop from hell!!';
END LOOP inifinite_loop;
5 cụ thể. Quan trọng không kém, các nhãn có thể được sử dụng để kiểm soát luồng thực thi, như chúng ta sẽ thấy trong các phần tiếp theo

hiển thị một vòng lặp rất đơn giản (và rất nguy hiểm). Nó sẽ tiếp tục mãi mãi, hoặc ít nhất là cho đến khi bạn xoay sở để chấm dứt nó bằng cách nào đó. Vì các chương trình được lưu trữ chạy bên trong máy chủ cơ sở dữ liệu nên việc sử dụng Ctrl-C hoặc các hình thức ngắt bàn phím khác sẽ không hiệu quả—bạn sẽ chỉ có thể chấm dứt vòng lặp này bằng cách đưa ra lệnh

    LEAVE label;
4 đối với phiên MySQL hoặc bằng cách tắt máy chủ cơ sở dữ liệu. Trong thời gian chờ đợi, vòng lặp sẽ tiêu thụ nhiều CPU nhất có thể, vì vậy chúng tôi khuyên bạn không nên chạy ví dụ này trên các hệ thống sản xuất quan trọng của mình

Ví dụ 4-19. Vòng lặp vô hạn (đừng thử ở nhà. )

Infinite_loop: LOOP
    SELECT 'Welcome to my infinite 
 loop from hell!!';
END LOOP inifinite_loop;

Rõ ràng là chúng ta hầu như không bao giờ muốn lập trình một vòng lặp vô hạn, và do đó chúng ta cần một số cách để kết thúc vòng lặp. Chúng ta có thể làm điều này với câu lệnh

    LEAVE label;
0, vì vậy hãy chuyển sang câu lệnh này ngay lập tức

Câu lệnh

    LEAVE label;
0 cho phép chúng ta kết thúc một vòng lặp. Cú pháp chung cho câu lệnh
    LEAVE label;
0 là

________số 8_______

    LEAVE label;
0 làm cho vòng lặp hiện tại bị chấm dứt. Nhãn phù hợp với vòng lặp sẽ bị kết thúc, vì vậy nếu một vòng lặp được đặt trong một vòng lặp khác, chúng ta có thể thoát ra khỏi cả hai vòng lặp bằng một câu lệnh

Trong trường hợp đơn giản nhất, chúng tôi chỉ thực hiện lệnh

    LEAVE label;
0 khi chúng tôi sẵn sàng thoát khỏi
Infinite_loop: LOOP
    SELECT 'Welcome to my infinite 
 loop from hell!!';
END LOOP inifinite_loop;
5, như thể hiện trong

Ví dụ 4-20. Sử dụng LEAVE để kết thúc một vòng lặp

SET i=1;
myloop: LOOP
    SET i=i+1;
    IF i=10 then
            LEAVE myloop;
    END IF;
END LOOP myloop;
SELECT 'I can count to 10';

    LEAVE label;
0 có thể được sử dụng để thoát khỏi bất kỳ cấu trúc vòng lặp thay thế nào, như chúng ta sẽ xem xét trong các phần sắp tới. Trên thực tế, bạn cũng có thể sử dụng
    LEAVE label;
0 nếu bạn muốn thoát ra khỏi khối có tên
    LEAVE label;
1 (được giới thiệu trước đó trong chương này)

Câu lệnh

SET i=1;
myloop: LOOP
    SET i=i+1;
    IF i=10 then
            LEAVE myloop;
    END IF;
END LOOP myloop;
SELECT 'I can count to 10';
4 được sử dụng để khởi động lại quá trình thực thi ở đầu vòng lặp mà không thực hiện bất kỳ câu lệnh nào còn lại trong vòng lặp.
SET i=1;
myloop: LOOP
    SET i=i+1;
    IF i=10 then
            LEAVE myloop;
    END IF;
END LOOP myloop;
SELECT 'I can count to 10';
4 có cú pháp như sau

    ITERATE label;

Khi MySQL gặp câu lệnh

SET i=1;
myloop: LOOP
    SET i=i+1;
    IF i=10 then
            LEAVE myloop;
    END IF;
END LOOP myloop;
SELECT 'I can count to 10';
4, nó sẽ đề xuất thực thi khi bắt đầu vòng lặp được chỉ định. Trong , chúng tôi in tất cả các số lẻ nhỏ hơn 10.
SET i=1;
myloop: LOOP
    SET i=i+1;
    IF i=10 then
            LEAVE myloop;
    END IF;
END LOOP myloop;
SELECT 'I can count to 10';
4 được sử dụng để lặp lại vòng lặp nếu số chúng ta có không phải là số lẻ.
    LEAVE label;
0 được sử dụng để kết thúc vòng lặp khi chúng tôi đạt đến 10

Ví dụ 4-21. Sử dụng ITERATE để quay lại điểm bắt đầu của một vòng lặp

SET i=0;
loop1: LOOP
    SET i=i+1;
    IF i>=10 THEN          /*Last number - exit loop*/
         LEAVE loop1;
    ELSEIF MOD(i,2)=0 THEN /*Even number - try again*/
         ITERATE loop1;
    END IF;


    SELECT CONCAT(i," is an odd number");


END LOOP loop1;

Mặc dù vòng lặp này rất hữu ích để minh họa việc sử dụng

    LEAVE label;
0 và
SET i=1;
myloop: LOOP
    SET i=i+1;
    IF i=10 then
            LEAVE myloop;
    END IF;
END LOOP myloop;
SELECT 'I can count to 10';
4 để điều khiển một vòng lặp, nhưng nó là một thuật toán được xây dựng khá kém. Chúng ta có thể dễ dàng giảm một nửa số lần lặp lại vòng lặp bằng cách tăng biến vòng lặp
    ITERATE label;
1 lên hai thay vì một

SET i=1;
myloop: LOOP
    SET i=i+1;
    IF i=10 then
            LEAVE myloop;
    END IF;
END LOOP myloop;
SELECT 'I can count to 10';
4 khiến việc thực thi vòng lặp bắt đầu lại ở đầu vòng lặp. Nếu bạn đang sử dụng vòng lặp
    ITERATE label;
3 (xem phần tiếp theo), điều này có nghĩa là vòng lặp sẽ thực hiện lại vô điều kiện, bỏ qua điều kiện
    ITERATE label;
4 mà nếu không vòng lặp sẽ kết thúc. Điều này có thể dẫn đến hành vi không mong muốn. Trong vòng lặp
    ITERATE label;
5,
SET i=1;
myloop: LOOP
    SET i=i+1;
    IF i=10 then
            LEAVE myloop;
    END IF;
END LOOP myloop;
SELECT 'I can count to 10';
4 sẽ dẫn đến điều kiện
    ITERATE label;
5 được đánh giá lại trước lần lặp tiếp theo của vòng lặp

Chúng ta có thể xây dựng bất kỳ dạng vòng lặp nào có thể tưởng tượng được bằng cách sử dụng các câu lệnh

Infinite_loop: LOOP
    SELECT 'Welcome to my infinite 
 loop from hell!!';
END LOOP inifinite_loop;
5,
    LEAVE label;
0 và
SET i=1;
myloop: LOOP
    SET i=i+1;
    IF i=10 then
            LEAVE myloop;
    END IF;
END LOOP myloop;
SELECT 'I can count to 10';
4. Tuy nhiên, trên thực tế, các vòng lặp “thủ công” này rất khó xử khi so sánh với một số lựa chọn thay thế mà chúng tôi sắp xem xét. Các câu lệnh
    ITERATE label;
5 và
    ITERATE label;
3 được mô tả trong các phần sau đây cho phép chúng tôi tạo các vòng lặp dễ viết, đọc và bảo trì hơn

Các câu lệnh

    ITERATE label;
3 và
    ITERATE label;
4 có thể được sử dụng để tạo một vòng lặp tiếp tục cho đến khi một số điều kiện logic được đáp ứng. Cú pháp của
SET i=0;
loop1: LOOP
    SET i=i+1;
    IF i>=10 THEN          /*Last number - exit loop*/
         LEAVE loop1;
    ELSEIF MOD(i,2)=0 THEN /*Even number - try again*/
         ITERATE loop1;
    END IF;


    SELECT CONCAT(i," is an odd number");


END LOOP loop1;
5 là

    [label:] REPEAT
        statements
    UNTIL expression
    END REPEAT [label]

Một vòng lặp

    ITERATE label;
3 tiếp tục cho đến khi biểu thức được xác định trong mệnh đề
    ITERATE label;
4 ước tính là TRUE. Về bản chất, một vòng lặp
    ITERATE label;
3 về mặt logic tương đương với một khối
SET i=0;
loop1: LOOP
    SET i=i+1;
    IF i>=10 THEN          /*Last number - exit loop*/
         LEAVE loop1;
    ELSEIF MOD(i,2)=0 THEN /*Even number - try again*/
         ITERATE loop1;
    END IF;


    SELECT CONCAT(i," is an odd number");


END LOOP loop1;
9 như thế này

    some_label:LOOP
        statements
        IF expression THEN LEAVE some_label; END IF;
    END LOOP;

Vòng lặp

    ITERATE label;
3 dễ bảo trì hơn một chút vì rõ ràng hơn điều kiện nào sẽ khiến vòng lặp kết thúc. Câu lệnh
    LEAVE label;
0 trong một vòng lặp đơn giản có thể ở bất kỳ đâu, trong khi câu lệnh
    ITERATE label;
4 luôn được liên kết với mệnh đề
    [label:] REPEAT
        statements
    UNTIL expression
    END REPEAT [label]
3 ở cuối vòng lặp. Hơn nữa, chúng ta không cần chỉ định nhãn cho vòng lặp
    ITERATE label;
3 vì điều kiện
    ITERATE label;
4 luôn dành riêng cho vòng lặp hiện tại. Tuy nhiên, chúng tôi vẫn khuyên bạn nên sử dụng nhãn có vòng lặp
    ITERATE label;
3 để cải thiện khả năng đọc, đặc biệt nếu các vòng lặp được lồng vào nhau

hiển thị sử dụng

    ITERATE label;
3 để in ra các số lẻ nhỏ hơn 10. So sánh cú pháp này với cú pháp của ví dụ trước bằng cách sử dụng các câu lệnh
Infinite_loop: LOOP
    SELECT 'Welcome to my infinite 
 loop from hell!!';
END LOOP inifinite_loop;
5 và
    LEAVE label;
0

Ví dụ 4-22. Ví dụ về vòng lặp REPEAT

SET i=0;
loop1: REPEAT
    SET i=i+1;
    IF MOD(i,2)<>0 THEN /*Even number - try again*/
       Select concat(i," is an odd number");
    END IF;
UNTIL i >= 10
END REPEAT;

Có một vài điều đáng chú ý về vòng lặp

    ITERATE label;
3

  • Một vòng lặp

        ITERATE label;
    3 luôn được đảm bảo chạy ít nhất một lần—tức là, điều kiện
        ITERATE label;
    4 được đánh giá lần đầu tiên sau lần thực hiện đầu tiên của vòng lặp. Đối với các vòng lặp không được chạy dù chỉ một lần trừ khi một số điều kiện được thỏa mãn, hãy sử dụng
        ITERATE label;
    5 (xem phần tiếp theo)

  • Sử dụng

    SET i=1;
    myloop: LOOP
        SET i=i+1;
        IF i=10 then
                LEAVE myloop;
        END IF;
    END LOOP myloop;
    SELECT 'I can count to 10';
    4 trong vòng lặp
        ITERATE label;
    3 có thể dẫn đến kết quả không mong muốn, vì làm như vậy sẽ bỏ qua phép thử
        ITERATE label;
    4 và có thể dẫn đến việc thực thi vòng lặp mặc dù điều kiện
        ITERATE label;
    4 không còn được thỏa mãn. Do đó, có thể bạn sẽ không muốn sử dụng
    SET i=1;
    myloop: LOOP
        SET i=i+1;
        IF i=10 then
                LEAVE myloop;
        END IF;
    END LOOP myloop;
    SELECT 'I can count to 10';
    4 trong vòng lặp
        ITERATE label;
    3

Một vòng lặp

    ITERATE label;
5 thực hiện miễn là một điều kiện là đúng. Nếu điều kiện không đúng ngay từ đầu, thì vòng lặp sẽ không bao giờ thực thi—không giống như vòng lặp
    ITERATE label;
3, được đảm bảo thực hiện ít nhất một lần

Vòng lặp

    ITERATE label;
5 có cú pháp như sau

    [label:] WHILE expression DO
        statements
    END WHILE [label]

Một vòng lặp

    ITERATE label;
5 có chức năng tương đương với một cấu trúc
SET i=0;
loop1: LOOP
    SET i=i+1;
    IF i>=10 THEN          /*Last number - exit loop*/
         LEAVE loop1;
    ELSEIF MOD(i,2)=0 THEN /*Even number - try again*/
         ITERATE loop1;
    END IF;


    SELECT CONCAT(i," is an odd number");


END LOOP loop1;
9 đơn giản có mệnh đề
    LEAVE label;
0 là câu lệnh đầu tiên của nó, như được mô tả trong phần “LỜI PHÁT BIỂU”. chứng minh
SET i=0;
loop1: REPEAT
    SET i=i+1;
    IF MOD(i,2)<>0 THEN /*Even number - try again*/
       Select concat(i," is an odd number");
    END IF;
UNTIL i >= 10
END REPEAT;
6

Ví dụ 4-23. LOOP-END LOOP thực hiện chức năng tương tự như vòng lặp WHILE

Infinite_loop: LOOP
    SELECT 'Welcome to my infinite 
 loop from hell!!';
END LOOP inifinite_loop;
0

hiển thị vòng lặp số lẻ ít hơn 10 của chúng tôi được triển khai bằng cách sử dụng

    ITERATE label;
5

Ví dụ 4-24. Các số lẻ nhỏ hơn 10 được triển khai dưới dạng vòng lặp WHILE

Infinite_loop: LOOP
    SELECT 'Welcome to my infinite 
 loop from hell!!';
END LOOP inifinite_loop;
1

Chúng ta thường muốn lồng các vòng lặp. Trong mã đơn giản trong , chúng tôi in ra “bảng thời gian” cơ bản bằng cách sử dụng cấu trúc

SET i=0;
loop1: LOOP
    SET i=i+1;
    IF i>=10 THEN          /*Last number - exit loop*/
         LEAVE loop1;
    ELSEIF MOD(i,2)=0 THEN /*Even number - try again*/
         ITERATE loop1;
    END IF;


    SELECT CONCAT(i," is an odd number");


END LOOP loop1;
9 lồng nhau

Ví dụ 4-25. Ví dụ về vòng lặp lồng nhau

Infinite_loop: LOOP
    SELECT 'Welcome to my infinite 
 loop from hell!!';
END LOOP inifinite_loop;
2

Khi lồng các vòng lặp, đặc biệt hữu ích khi gắn nhãn bắt đầu và kết thúc vòng lặp để liên kết rõ ràng phần đầu của mỗi vòng lặp với phần cuối của nó. Tất nhiên, nếu chúng ta cần sử dụng

    LEAVE label;
0, chúng ta phải gắn nhãn cho vòng lặp

Nhận xét chia tay trên vòng lặp

Bây giờ chúng ta đã thấy ba thuật toán lặp đơn giản và giống hệt nhau được triển khai bằng cách sử dụng ba cấu trúc lặp có sẵn trong ngôn ngữ chương trình được lưu trữ MySQL. Mỗi cấu trúc trong số ba cấu trúc vòng lặp có khả năng thực hiện hầu như bất kỳ logic vòng lặp nào mà bạn có thể cần thực hiện

Các vòng lặp ví dụ được đưa ra trong chương này khá đơn giản và ít liên quan đến thế giới thực. Chúng tôi làm điều này một phần vì mục đích rõ ràng, nhưng cũng vì thực tế là trong lập trình được lưu trữ, hầu hết tất cả các cấu trúc vòng lặp của bạn sẽ liên quan đến việc lặp qua các hàng được trả về bởi câu lệnh

Infinite_loop: LOOP
    SELECT 'Welcome to my infinite 
 loop from hell!!';
END LOOP inifinite_loop;
3, đây là chủ đề của chương tiếp theo

Làm cách nào để LOOP trong thủ tục lưu trữ MySQL?

Cú pháp chung để triển khai một vòng lặp MySQL đơn giản là. .
[bắt đầu_nhãn. ] VÒNG. tuyên bố_list. VÒNG KẾT THÚC [end_label]
[Tên]. VÒNG. tuyên_bố; . RỜI [nhãn];
THỦ TỤC XẢ NẾU TỒN TẠI loopMe; . KHAI BÁO tôi INT;

Làm cách nào để sử dụng LOOP trong thủ tục lưu trữ SQL Server?

Thủ tục lưu sẵn SQL Server cho vòng lặp .
Nói chung, khi bạn sử dụng vòng lặp FOR trong bất kỳ ngôn ngữ lập trình nào, bạn sẽ thực hiện một tác vụ trong một số lần cụ thể. .
Trong hầu hết các ngôn ngữ lập trình, có một giá trị ban đầu, một điều kiện và một giá trị gia tăng trong vòng lặp For

Làm cách nào để LOOP một truy vấn trong MySQL?

LOOP thực hiện một cấu trúc vòng lặp đơn giản, cho phép thực hiện lặp lại danh sách câu lệnh, bao gồm một hoặc nhiều câu lệnh, mỗi câu lệnh được kết thúc bằng dấu chấm phẩy ( ; ) dấu phân cách câu lệnh. Các câu lệnh trong vòng lặp được lặp lại cho đến khi vòng lặp kết thúc. Thông thường, điều này được thực hiện với câu lệnh LEAVE

MySQL có vòng lặp for không?

Chúng có thể trả về tập kết quả trong trường hợp bạn sử dụng câu lệnh SELECT; . Bạn cũng có thể tạo các hàm trong MYSQL. Tương tự như các ngôn ngữ lập trình khác MySQL cung cấp hỗ trợ cho các câu lệnh điều khiển luồng như IF, CASE, ITERATE, LEAVE LOOP, WHILE và REPEAT .