Panoramica sui Cursori
Spiegazione
I cursori sono strutture che permettono di scorrere i risultati in modo sequenziale ed effettuare operazioni sui risultati.
MariaDB permette l'uso dei cursori negli Stored Program. I cursori di MariaDB sono non-riavvolgibili, di sola lettura e asensitive.
- Non-riavvolgibili significa che i risultati possono essere letti solo nell'ordine determinato dall'istruzione SELECT. Non è possibile saltare delle righe, né spostarsi a una data posizione, né estrarre le righe in ordine inverso.
- Sola lettura significa che i dati non possono essere modificati tramite il cursore.
- Asensitive significa che il cursore punta ai dati che si trovano effettivamente nelle tabelle. I cursori di questo genere sono più veloci rispetto all'alternativa, i cursori insensitive, perché i dati non vengono copiati in una tabella temporanea. Tuttavia modificando questi dati si modificano anche i dati letti dal cursore.
I cursori possono essere dichiarati con l'istruzione DECLARE CURSOR e aperti con OPEN. Le righe possono essere lette con FETCH. Infine il cursore si chiude con l'istruzione CLOSE.
When FETCH is issued and there are no more rows to extract, the following error is produced:
ERROR 1329 (02000): No data - zero rows fetched, selected, or processed
To avoid problems, a DECLARE HANDLER statement is generally used. The HANDLER should handler the 1329 error, or the '02000' SQLSTATE, or the NOT FOUND error class.
Only SELECT statements are allowed for cursors, and they cannot be contained in a variable - so, they cannot be composed dynamically. However, it is possible to SELECT from a view. Since the CREATE VIEW statement can be executed as a prepared statement, it is possible to dynamically create the view that is queried by the cursor.
Example
CREATE TABLE c1(i INT); CREATE TABLE c2(i INT); CREATE TABLE c3(i INT); DELIMITER // CREATE PROCEDURE p1() BEGIN DECLARE done INT DEFAULT FALSE; DECLARE x, y INT; DECLARE cur1 CURSOR FOR SELECT i FROM test.c1; DECLARE cur2 CURSOR FOR SELECT i FROM test.c2; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; OPEN cur1; OPEN cur2; read_loop: LOOP FETCH cur1 INTO x; FETCH cur2 INTO y; IF done THEN LEAVE read_loop; END IF; IF x < y THEN INSERT INTO test.c3 VALUES (x); ELSE INSERT INTO test.c3 VALUES (y); END IF; END LOOP; CLOSE cur1; CLOSE cur2; END; // DELIMITER ; INSERT INTO c1 VALUES(5),(50),(500); INSERT INTO c2 VALUES(10),(20),(30); CALL p1; SELECT * FROM c3; +------+ | i | +------+ | 5 | | 20 | | 30 | +------+