Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Làm cách nào để tôi có thể lặp qua tất cả các hàng của bảng? (MySQL)

Vì gợi ý của một vòng lặp ngụ ý yêu cầu giải pháp kiểu thủ tục. Của tôi đây.

Bất kỳ truy vấn nào hoạt động trên bất kỳ bản ghi nào được lấy từ một bảng đều có thể được bao bọc trong một thủ tục để làm cho nó chạy qua từng hàng của bảng như sau:

Trước tiên, hãy xóa mọi thủ tục hiện có có cùng tên và thay đổi dấu phân cách để SQL của bạn không cố chạy từng dòng khi bạn đang cố viết thủ tục.

DROP PROCEDURE IF EXISTS ROWPERROW;
DELIMITER ;;

Sau đó, đây là quy trình theo ví dụ của bạn (table_A và table_B được sử dụng để rõ ràng)

CREATE PROCEDURE ROWPERROW()
BEGIN
DECLARE n INT DEFAULT 0;
DECLARE i INT DEFAULT 0;
SELECT COUNT(*) FROM table_A INTO n;
SET i=0;
WHILE i<n DO 
  INSERT INTO table_B(ID, VAL) SELECT (ID, VAL) FROM table_A LIMIT i,1;
  SET i = i + 1;
END WHILE;
End;
;;

Sau đó, đừng quên đặt lại dấu phân cách

DELIMITER ;

Và chạy thủ tục mới

CALL ROWPERROW();

Bạn có thể làm bất cứ điều gì bạn thích tại dòng "CHÈN VÀO" mà tôi chỉ cần sao chép từ yêu cầu mẫu của bạn.

Lưu ý CẨN THẬN rằng dòng "CHÈN VÀO" được sử dụng ở đây phản ánh dòng trong câu hỏi. Theo các nhận xét cho câu trả lời này, bạn cần đảm bảo rằng truy vấn của bạn chính xác về mặt cú pháp cho phiên bản SQL nào bạn đang chạy.

Trong trường hợp đơn giản, trường ID của bạn được tăng dần và bắt đầu từ 1 dòng trong ví dụ có thể trở thành:

INSERT INTO table_B(ID, VAL) VALUES(ID, VAL) FROM table_A WHERE ID=i;

Thay thế dòng "SELECT COUNT" bằng

SET n=10;

Sẽ cho phép bạn kiểm tra truy vấn của mình trên 10 bản ghi đầu tiên chỉ trong table_A.

Một điều cuối cùng. Quá trình này cũng rất dễ dàng để lồng vào các bảng khác nhau và là cách duy nhất tôi có thể thực hiện một quy trình trên một bảng để chèn động các số lượng bản ghi khác nhau vào một bảng mới từ mỗi hàng của bảng mẹ.

Nếu bạn cần nó chạy nhanh hơn thì hãy cố gắng đặt nó dựa trên, nếu không thì điều này cũng ổn. Bạn cũng có thể viết lại phần trên ở dạng con trỏ nhưng nó có thể không cải thiện hiệu suất. ví dụ:

DROP PROCEDURE IF EXISTS cursor_ROWPERROW;
DELIMITER ;;

CREATE PROCEDURE cursor_ROWPERROW()
BEGIN
  DECLARE cursor_ID INT;
  DECLARE cursor_VAL VARCHAR;
  DECLARE done INT DEFAULT FALSE;
  DECLARE cursor_i CURSOR FOR SELECT ID,VAL FROM table_A;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
  OPEN cursor_i;
  read_loop: LOOP
    FETCH cursor_i INTO cursor_ID, cursor_VAL;
    IF done THEN
      LEAVE read_loop;
    END IF;
    INSERT INTO table_B(ID, VAL) VALUES(cursor_ID, cursor_VAL);
  END LOOP;
  CLOSE cursor_i;
END;
;;

Hãy nhớ khai báo các biến bạn sẽ sử dụng cùng kiểu với các biến từ các bảng đã truy vấn.

Lời khuyên của tôi là hãy sử dụng các truy vấn setbased khi bạn có thể và chỉ sử dụng các vòng lặp hoặc con trỏ đơn giản nếu bạn phải làm như vậy.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách Chèn Nhiều Hàng trong MySQL

  2. Sâu bọ? # 1146 - Bảng 'xxx.xxxxx' không tồn tại

  3. Cách Tham gia MySQL và Postgres trong Chế độ xem Trực tiếp Vật chất hóa

  4. Percona Live Dublin - Tóm tắt sự kiện và các phiên của chúng tôi

  5. Trình hướng dẫn Entity Framework gặp sự cố trên MySQL