Hướng dẫn mysql procedure cursor - con trỏ thủ tục mysql

13.6.6 Cursors

MySQL supports cursors inside stored programs. The syntax is as in embedded SQL. Cursors have these properties:

  • Asensitive: The server may or may not make a copy of its result table

  • Read only: Not updatable

  • Nonscrollable: Can be traversed only in one direction and cannot skip rows

Cursor declarations must appear before handler declarations and after variable and condition declarations.

Example:

CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;


Nội dung chính ShowShow

  • 13.6.6 Cursors
  • Khai báo và sử dụng Cursor
  • Tóm tắt lại các câu lệnh
  • Kết nối tới MySQL Server
  • Tạo User và Database
  • Tạo bảng
  • Thêm bản ghi
  • Thực hiện truy vấn
  • Thực hiện Transaction
  • Tạo Stored Procedure
  • Chơi với các biến
  • Chơi với Cursors
  • Điều khiển luồng
  • Tạo Trigger
  • Tạo một Scheduled Event

13.6.6 Cursors

Scheduled Event là một trigger được thực thi vào một tời điểm cụ thể nào đó. Có sự kiện diễn ra 1 lần, lên lịch vào ngày, giờ cụ thể nào đó, hoặc là các sự kiện định kì, chạy vào mỗi phút, giờ, ngày,... trong 1 khoảng thời gian cố định.

  • MySQL rất là phức tạp và có quá nhiều thứ để nói, không thể trình bày hết trong bài viết này. Tuy nhiên những điều trên chắc cũng khá đủ cho phần lớn các mục đích thông thường, nếu cần nhiều hơn, bạn có thể tham khảo tài liệu chính thức này.

  • Nguồn: //medium.com/better-programming/the-mysql-cheatsheet-we-all-need-d1af0377bdc6

  • Nội dung chính Show

Khai báo và sử dụng Cursor

Tóm tắt lại các câu lệnh

Kết nối tới MySQL Server

Khai báo và sử dụng Cursor

Tạo User và Database

Tạo bảng

Thêm bản ghi

MySQL supports cursors inside stored programs. The syntax is as in embedded SQL. Cursors have these properties:

Asensitive: The server may or may not make a copy of its result table

Read only: Not updatable

Nonscrollable: Can be traversed only in one direction and cannot skip rows

Cursor declarations must appear before handler declarations and after variable and condition declarations. 7] bằng lệnh
DECLARE cursorProduct CURSOR FOR
SELECT id, title FROM Product
8
khai báo con trỏ, trỏ đến một tập dữ liệu [kết quả của

Example:

CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
Khai báo và sử dụng Cursor

CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
1

Trong các truy vấn T-SQL, như tại các Stored Procedure, ta có thể sử dụng các con trỏ

DECLARE cursorProduct CURSOR FOR
SELECT id, title FROM Product
2 để duyệt qua dữ liệu. Ta hiểu
DECLARE cursorProduct CURSOR FOR
SELECT id, title FROM Product
2 là một tập hợp kết quả truy vấn [các hàng], với
DECLARE cursorProduct CURSOR FOR
SELECT id, title FROM Product
2 ta có thể duyệt qua từng hàng kết quả để thi hành những tác vụ phức tạp.

Ở một thời điểm, Khi bắt đầu quá trình đọc các dòng dữ liệu từ Cursor trên, thì phải mở con trỏ, thực hiện như sau:

CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
4

DECLARE cursorProduct CURSOR FOR
SELECT id, title FROM Product
2 có thể truy cập bởi một con trỏ đến một hàng của nó, bạn chỉ thể dịch chuyển con trỏ từ dòng này sang dòng khác.

CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
40Cursor được mở, con trỏ sẽ trỏ tới dòng đầu tiên của tập dữ liệu, lúc này có thể đọc nội dung dòng đó bằng lệnh
CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
40Cursor được mở, con trỏ sẽ trỏ tới dòng đầu tiên của tập dữ liệu, lúc này có thể đọc nội dung dòng đó bằng lệnh
CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
40

Bước 3: Đọc dữ liệu sử dụng lệnh như sau: Đọc dữ liệu sử dụng lệnh như sau: Đọc dữ liệu sử dụng lệnh như sau:

CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
7

Lệnh trên sẽ đọc nội dung dòng hiện tại, lưu vào biến @id và @title [vì dữ liệu trong Cursor này có 2 cột]. Nếu đọc thành công thì dịch chuyển con trỏ tới dòng tiếp theo

Để kiệm tra việc

CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
41 thành công thì kiểm tra điều kiện
CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
42

Kết hợp những điều trên lại, để đọc từng dòng từ đầu đến cuối sẽ làm như sau:

DECLARE cursorProduct CURSOR FOR
SELECT id, title FROM Product
0

Bước 4: sau khi không còn dùng đến Cursor, cần đóng lại và giải phóng các tài nguyên nó chiếm giữ sau khi không còn dùng đến Cursor, cần đóng lại và giải phóng các tài nguyên nó chiếm giữ sau khi không còn dùng đến Cursor, cần đóng lại và giải phóng các tài nguyên nó chiếm giữ

DECLARE cursorProduct CURSOR FOR
SELECT id, title FROM Product
1

Tóm tắt lại các câu lệnh

Các câu lệnh sử dụng Cursor ở trên, tổng hợp lại trong một ví dụ hoàn chỉnh như sau:

DECLARE cursorProduct CURSOR FOR
SELECT id, title FROM Product
2

MySQL rất là phổ biến, được sử dụng nhiều, nhưng mọi người thường hay quên mất cú pháp của nó, lúc nào cần dùng lại đi tra google. Vì thế bài viết này sẽ tổng hợp lại các cú pháp, từ cơ bản cho đến nâng cao, để lúc nào cần mọi người có thể tiện sử dụng luôn.

Kết nối tới MySQL Server

Bước đầu tiên để làm việc với MySQL database là kết nối với nó. Trong terminal, gõ lệnh:

DECLARE cursorProduct CURSOR FOR
SELECT id, title FROM Product
3

Nếu server và client đều chạy trên cùng 1 máy, không cần thiết phải thêm

CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
43.
CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
44 cũng không bắt buộc, vì trong phần tiếp theo, ta sẽ thấy có thể tạo và thay đổi database hiện tại chỉ với 1 câu lệnh. Để kết thúc kết nối tới MySQL, ta có thể gõ
CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
45,
CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
46 hoặc
CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
47.

Tạo User và Database

MySQL làm việc với user mặc định là root, tuy nhiên nó chỉ nên dùng để quản lý database, không phải để thao tác dữ liệu. Đó là lý do chúng ta nên tạo user.

DECLARE cursorProduct CURSOR FOR
SELECT id, title FROM Product
9

Đoạn code trên, chúng ta không tạo ra 2 user, mà là 1 user có thể sử dụng được kể cả khi client ở trong hay bên ngoài server. Giờ chúng ta sẽ xem cách để tạo database và phân quyền cho các user khác nhau.

CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
10

Tạo bảng

Bảng là khái niệm cốt lõi của hệ quản trị cơ sở dữ liệu như MySQL. Chúng ta sẽ học cách tạo bảng đơn giản, và cách để set primary keys, restrictions, foreign keys, và giá trị mặc định.

CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
11

Thêm bản ghi

Sau khi tạo bảng, bước tiếp theo là thêm data. Ví dụ tiếp theo bao gồm cả cách thêm 1 bản ghi và nhiều bản ghi cùng lúc

CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
12

Thực hiện truy vấn

Truy vấn sẽ được hoàn thành chỉ với một câu lệnh

CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
48, nó cho phép chúng ta lấy dữ liệu từ database. MySQL cho phép chúng ta thực hiện các câu truy vấn phức tạp, lấy dữ liệu từ nhiều bảng hoặc tạo các toán tử logic từ kết quả của các câu query khác.
CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
13

Tạo View

View cho phép chúng ta gói lệnh

CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
48 vào trong 1 view giống như 1 bảng mới. Sau đó chúng ta có thể set quyền cho các user đối với view đó. Tuy nhiên, nếu như lệnh
CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
48 được gói có các hàm tính toán như
CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
71,
CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
72,... hoặc sử dụng
CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
73,
CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
74,... thì không thể thực hiện các thao tác
CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
75,
CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
76, hay
CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
77 với view đó.
CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
14

Thực hiện Transaction

Transaction là 1 nhóm các lệnh, nếu 1 lệnh trong transaction không thành công MySQL sẽ hoàn tác lại các lệnh trước đó.

CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
15

Tạo Stored Procedure

Stored Procedure là một chuỗi câu SQL có thể được gọi bất cứ lúc nào từ console hay file

CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
78. Nó tương tự như function trong các ngôn ngữ lập trình.
CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
16

Chơi với các biến

Biến là một cách hữu dụng để lưu trữ tạm thời kết quả của câu query hoặc giá trị của 1 cột trong một bản ghi để dùng sau. Có 2 loại biến chính trong MySQL: local và user-defined [hay còn gọi là biến session]. Loại đầu tiên được khai báo trước khi sử dụng, và phạm vi của chúng được giới hạn trong

CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
79, nơi định nghĩa chúng. Loại thứ 2 không phải khai báo trước, giá trị của nó có thể sử dụng bất cứ lúc nào, nhưng chỉ trong session được tạo bởi client.
CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
17

Chơi với Cursors

Cursor là một công cụ giống như vòng lặp chạy qua từng bản ghi trong kết quả của câu truy vấn. Nó sẽ rất hữu dụng khi muốn chuyển mỗi bản ghi thành 1 object chẳng hạn. Cách khai báo và sử dụng cũng rất dễ dàng:

CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
18

Điều khiển luồng

Bên trong stored procedure, chúng ta có thể điều khiến luồng, giống như trong các ngôn ngữ lập trình khác

CREATE PROCEDURE curdemo[]
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR[16];
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES [a,b];
    ELSE
      INSERT INTO test.t3 VALUES [a,c];
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
19

Tạo Trigger

Trigger là một phương thức được chạy trước hoặc sau một hành động nào đó, ví dụ như insert, update, hay delete trong table hoặc view. Chúng ta cần cẩn thận với trigger vì nó có thể tốn khá nhiều tài nguyên server.

DECLARE cursorProduct CURSOR FOR
SELECT id, title FROM Product
0

Tạo một Scheduled Event

Scheduled Event là một trigger được thực thi vào một tời điểm cụ thể nào đó. Có sự kiện diễn ra 1 lần, lên lịch vào ngày, giờ cụ thể nào đó, hoặc là các sự kiện định kì, chạy vào mỗi phút, giờ, ngày,... trong 1 khoảng thời gian cố định.

DECLARE cursorProduct CURSOR FOR
SELECT id, title FROM Product
1

MySQL rất là phức tạp và có quá nhiều thứ để nói, không thể trình bày hết trong bài viết này. Tuy nhiên những điều trên chắc cũng khá đủ cho phần lớn các mục đích thông thường, nếu cần nhiều hơn, bạn có thể tham khảo tài liệu chính thức này.

Nguồn: //medium.com/better-programming/the-mysql-cheatsheet-we-all-need-d1af0377bdc6

Bài Viết Liên Quan

Chủ Đề