Your cart is currently empty!
Category: sql
-
Khóa học miễn phí SQL – Cursors nhận dự án làm có lương
SQL – Cursors
Table of content
A database cursor solves the problem of impedance mismatch. It acts as a filter between the result of a SQL query and the statements that process this result.
Cursors in SQL
A Cursor is a temporary memory that is allocated by the database server at the time of performing the Data Manipulation Language operations on a table, such as INSERT, UPDATE and DELETE etc. It is used to retrieve and manipulate data stored in the SQL table.
In MySQL, you cannot declare a cursor directly outside of a stored procedure or function. Cursors are generally declared within stored procedures, functions, or blocks of SQL code in MySQL database.
Using cursors, we can perform multiple operations on each row of a result set, with or without returning the original data.
Properties of Cursors
Following are the properties of MySQL Cursors −
-
READ ONLY − We cannot update or modify any records in the table using the MySQL cursors. We can just fetch and process data from a table.
-
Non-Scrollable − We can retrieve records from a table in a single direction, i.e. from the first record or the last. We cannot move backward or jump to a specific position within the result set.
-
Asensitive Cursor − An asensitive cursor operates directly on the actual data in the database, it does not create a copy of the data. If any change is made to the data by other connections, it can affect the data that the cursor is working with.
In addition to the Asensitive cursor there is another type known as Insensitive Cursor. An insensitive cursor uses a temporary copy of the data. Therefore, these cursors are insensitive (not affected) to the changes that are made in the table.
Life Cycle of the Cursor
There are four steps to manage these cursors. Following diagram illustrates the lifecycle of an SQL cursor −
Now, let us discuss the phases of life cycle of the cursor one-by-one.
Declare Cursor Statement
In MySQL we can declare a cursor using the DECLARE statement and associate it with a SELECT statement to retrieve records from a database table.
However, this SELECT statement associated with a cursor does not use the INTO clause, as it”s purpose is to fetch and process rows rather than assigning values to variables.
Syntax
Following is the syntax to declare a cursor in MySQL database −
DECLARE cursor_name CURSOR FOR select_statement;
Open Cursor Statement
After declaring a cursor in MySQL, the next step is to open the cursor using the OPEN statement. It initializes the result-set, allowing us to fetch and process rows from the associated SELECT statement in the cursor.
Syntax
Following is the syntax to open a cursor in MySQL database −
OPEN cursor_name;
Fetch Cursor Statement
Then, we can use the FETCH statement to retrieve the current row pointed by the cursor, and with each FETCH, the cursor moves to the next row in the result set. This allows us to process each row one by one.
Syntax
Following is the syntax to fetch a cursor in MySQL database −
FETCH cursor_name INTO variable_list;
Close Cursor Statement
Once all the rows are fetched, we must close the cursor to release the memory associated with it. We can do this using the CLOSE statement.
Syntax
Following is the syntax to close a cursor in MySQL database −
CLOSE cursor_name;
Example
In this example, let us see how to manage a cursor in a stored procedure.
Assume we have created a table with the name CUSTOMERS using the CREATE TABLE statement as follows −
CREATE TABLE CUSTOMERS ( ID INT NOT NULL, NAME VARCHAR (20) NOT NULL, AGE INT NOT NULL, ADDRESS CHAR (25), SALARY DECIMAL (18, 2), PRIMARY KEY (ID) );
Now, let us insert some records into the CUSTOMERS table using the INSERT statement as follows −
INSERT INTO CUSTOMERS VALUES (1, ''Ramesh'', 32, ''Ahmedabad'', 2000.00 ), (2, ''Khilan'', 25, ''Delhi'', 1500.00 ), (3, ''Kaushik'', 23, ''Kota'', 2000.00 ), (4, ''Chaitali'', 25, ''Mumbai'', 6500.00 );
Now, we will create a backup table named ”CUSTOMERS_BACKUP” to store customer data −
CREATE TABLE CUSTOMERS_BACKUP ( ID INT NOT NULL, NAME VARCHAR (20) NOT NULL, PRIMARY KEY (ID) );
Here, we are creating a stored procedure named FetchCustomers to fetch customer names from the CUSTOMERS table and inserting them one by one into the BACKUP table. We are using a cursor to iterate through the rows and a handler to detect the end of the result-set, ensuring all names are processed −
DELIMITER // CREATE PROCEDURE FetchCustomers() BEGIN DECLARE done INT DEFAULT FALSE; DECLARE customer_id INT; DECLARE customer_name VARCHAR(255); DECLARE auto_id INT; -- Declare cursor DECLARE MY_CURSOR CURSOR FOR SELECT id, name FROM CUSTOMERS; -- Declare exit handler DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; -- Open cursor OPEN MY_CURSOR; -- Fetch and insert rows read_loop: LOOP FETCH MY_CURSOR INTO customer_id, customer_name; IF done = 1 THEN LEAVE read_loop; END IF; -- Insert the fetched data into the backup table INSERT INTO customers_backup VALUES (customer_id, customer_name); -- Get the last auto-generated ID used in the insertion SET auto_id = LAST_INSERT_ID(); END LOOP; -- Close cursor CLOSE MY_CURSOR; END // DELIMITER ;
Once we create the procedure successfully, we can execute it using the CALL statement as shown below −
CALL FetchCustomers();
Verification
You can verify the contents of the CUSTOMERS_BACKUP table using the SELECT statement as shown below −
SELECT * FROM CUSTOMERS_BACKUP;
The contents of the table would be −
ID NAME 1 Ramesh 2 Khilan 3 Kaushik 4 Chaitali
Khóa học lập trình tại Toidayhoc vừa học vừa làm dự án vừa nhận lương: Khóa học lập trình nhận lương tại trung tâm Toidayhoc
-
Khóa học miễn phí SQL – Common Table Expression nhận dự án làm có lương
SQL – Common Table Expression (CTE)
A Common Table Expression (CTE) can make it easier to manage and write complex queries by making them more readable and simple, like database views and derived tables. We can reuse or rewrite the query by breaking down the complex queries into simple blocks.
The SQL Common Table Expression
The WITH clause in MySQL is used to specify a Common Table Expression.
A Common Table Expression (CTE) in SQL is a one-time result set, i.e. it is a temporary table that exists only during the execution of a single query. It allows us to work with data specifically within that query, such as using it in SELECT, UPDATE, INSERT, DELETE, CREATE, VIEW, OR MERGE statements.
CTE is temporary because it cannot be stored anywhere for later use; once the query is executed, it is lost.
The MySQL WITH Clause
To specify common table expressions, we use WITH clause that consists of one or more comma-separated subclauses. Within each subclause, we can present a subquery that produces a result set and assigns a name to this subquery.
You cannot use the WITH clause in MySQL versions before 8.0.
Syntax
Following is the syntax to create a CTE using WITH clause −
WITH CTE_NAME (column_name) AS (query) SELECT * FROM CTE_NAME;
Where,
- CTE_NAME − It is the name assigned to the CTE.
- column_name − It is the column names for the CTE, which can be useful for improving query readability.
- query − It defines the CTE and it can be any valid SQL query.
- After defining the CTE, you can reference it in subsequent queries within the same session.
Example
Assume we have created a table named CUSTOMERS in MySQL database using CREATE TABLE statement as shown below −
CREATE TABLE CUSTOMERS ( ID INT NOT NULL, NAME VARCHAR (20) NOT NULL, AGE INT NOT NULL, ADDRESS CHAR (25), SALARY DECIMAL (18, 2), PRIMARY KEY (ID) );
Now, we are inserting some records into the above created table −
INSERT INTO CUSTOMERS VALUES (1, ''Ramesh'', 32, ''Ahmedabad'', 2000.00 ), (2, ''Khilan'', 25, ''Delhi'', 1500.00 ), (3, ''Kaushik'', 23, ''Kota'', 2000.00 ), (4, ''Chaitali'', 25, ''Mumbai'', 6500.00 ), (5, ''Hardik'', 27, ''Bhopal'', 8500.00 ), (6, ''Komal'', 22, ''Hyderabad'', 4500.00 ), (7, ''Muffy'', 24, ''Indore'', 10000.00 );
The table created is as shown below −
ID | NAME | AGE | ADDRESS | SALARY |
---|---|---|---|---|
1 | Ramesh | 32 | Ahmedabad | 2000.00 |
2 | Khilan | 25 | Delhi | 1500.00 |
3 | Kaushik | 23 | Kota | 2000.00 |
4 | Chaitali | 25 | Mumbai | 6500.00 |
5 | Hardik | 27 | Bhopal | 8500.00 |
6 | Komal | 22 | Hyderabad | 4500.00 |
7 | Muffy | 24 | Indore | 10000.00 |
Here, we are creating a Common Table Expression (CTE) named CUSTOMER_AGE that selects all customers with an age of 23. We are then retrieving the ID, NAME, and AGE of these customers from the CTE.
WITH CUSTOMER_AGE AS ( SELECT * FROM customers WHERE AGE = 23) SELECT ID, NAME, AGE FROM CUSTOMER_AGE;
Output
Following is the output of the above query −
ID | NAME | AGE |
---|---|---|
3 | Kaushik | 23 |
CTE from Multiple Tables
We can also create a Common Table Expression (CTE) that combines data from multiple tables by using JOIN operations within the CTE”s subquery. To do this, we need to use the comma operator to separate each CTE definition, effectively merging them into a single statement.
Syntax
Following is the basic syntax for multiple Common Table Expression (CTE) −
WITH CTE_NAME1 (column_name) AS (query), CTE_NAME2 (column_name) AS (query) SELECT * FROM CTE_NAME1 UNION ALL SELECT * FROM CTE_NAME2;
We can use multiple Common Table Expressions (CTEs) with various SQL operations, such as UNION, UNION ALL, JOIN, INTERSECT, or EXCEPT.
Example
In here, we are defining two CTEs namely ”CUSTOMERS_IN_DELHI” and ”CUSTOMERS_IN_MUMBAI” to segregate customers based on their addresses in Delhi and Mumbai. Then, we are using the UNION ALL operator to combine the results from both CTEs into a single result set, retrieving customer information from both cities.
WITH CUSTOMERS_IN_DELHI AS ( SELECT * FROM CUSTOMERS WHERE ADDRESS = ''Delhi''), CUSTOMERS_IN_MUMBAI AS ( SELECT * FROM CUSTOMERS WHERE ADDRESS = ''Mumbai'') SELECT ID, NAME, ADDRESS FROM CUSTOMERS_IN_DELHI UNION ALL SELECT ID, NAME, ADDRESS FROM CUSTOMERS_IN_MUMBAI;
Output
Output of the above query is as shown below −
ID | NAME | ADDRESS |
---|---|---|
2 | Khilan | Delhi |
4 | Chaitali | Mumbai |
Recursive CTE
A common table expression is a query that keeps referring back to its own result in a loop repeatedly until it returns an empty result.
A recursive query continually iterates across a subset of the data during its execution, and defines itself in a self-referencing manner. This self-referencing mechanism allows it to repeatedly process and expand its results until a stopping condition is met.
To make a CTE recursive, it must include a UNION ALL statement and provide a second definition of the query that utilizes the CTE itself. This allows the CTE to repeatedly reference to its own results, creating a recursive behaviour in the query.
Example
Now, we are using a recursive CTE named recursive_cust to retrieve data from the ”CUSTOMERS” table created above. Initially, we are selecting customers with salaries above 3000 and then recursively appending customers older than 25 to the result set using the UNION ALL operator −
WITH recursive_cust (ID, NAME, ADDRESS, AGE) AS ( SELECT ID, NAME, ADDRESS, AGE FROM CUSTOMERS WHERE SALARY > 3000 UNION ALL SELECT ID, NAME, ADDRESS, AGE FROM CUSTOMERS WHERE AGE > 25 ) SELECT * FROM recursive_cust;
Output
When the above query is executed, all data from the customers table whose age is greater than 25 or salary is greater than 3000 will be displayed recursively as shown below −
ID | NAME | ADDRESS | AGE |
---|---|---|---|
4 | Chaitali | Mumbai | 25 |
5 | Hardik | Bhopal | 27 |
6 | Komal | Hyderabad | 22 |
7 | Muffy | Indore | 24 |
1 | Ramesh | Ahmedabad | 32 |
5 | Hardik | Bhopal | 27 |
Example
In the following query, we are using a recursive CTE named Numbers to generate and display numbers from 1 to 5. The recursive part continually adds 1 to the previous value until it reaches 5, creating a sequence −
WITH RECURSIVE Numbers AS ( SELECT 1 AS N UNION ALL SELECT N + 1 FROM Numbers WHERE N < 5 ) SELECT n FROM Numbers;
Output
After executing the above query, we get the following output −
N |
---|
1 |
2 |
3 |
4 |
5 |
Advantages of CTE
Following are the advantages of the CTE −
-
CTE makes the code maintenance easier.
-
It increases the readability of the code.
-
It increases the performance of the query.
-
CTE allows for the simple implementation of recursive queries.
Disadvantages of CTE
Following are the disadvantages of the CTE −
-
CTE can only be referenced once by the recursive member.
-
We cannot use the table variables and CTEs as parameters in a stored procedure.
-
A CTE can be used in place of a view, but a CTE cannot be nested while views can.
Khóa học lập trình tại Toidayhoc vừa học vừa làm dự án vừa nhận lương: Khóa học lập trình nhận lương tại trung tâm Toidayhoc