Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Dynamischer Cursor in gespeicherter Prozedur

Aus dem MySQL-Handbuch

Es gibt jedoch 2 Möglichkeiten.

Die erste ist für Fälle, in denen absolut nur ein Benutzer gleichzeitig die Prozedur ausführt. Eine Prepare-Anweisung kann verwendet werden, um eine Ansicht mit dem dynamischen SQL zu erstellen, und der Cursor kann aus dieser statisch benannten Ansicht auswählen. Es gibt fast keine Auswirkungen auf die Leistung. Leider sind diese Ansichten auch für andere Benutzer sichtbar (es gibt keine temporäre Ansicht), daher funktioniert dies nicht für mehrere Benutzer.

Analog kann in der Prepare-Anweisung eine temporäre Tabelle angelegt werden und der Cursor kann aus der temporären Tabelle auswählen. Nur die aktuelle Sitzung kann eine temporäre Tabelle sehen, sodass das Problem mit mehreren Benutzern behoben ist. Diese Lösung kann jedoch erhebliche Auswirkungen auf die Leistung haben, da bei jeder Ausführung des Prozesses eine temporäre Tabelle erstellt werden muss.

Fazit:Wir brauchen noch Cursor, um dynamisch erstellt werden zu können!

Hier ist ein Beispiel für die Verwendung einer Ansicht zum Übergeben des Tabellennamens und Spaltennamens an einen Cursor aus Mysql-Foren

DELIMITER // 
DROP PROCEDURE IF EXISTS test_prepare// 

CREATE PROCEDURE test_prepare(IN tablename varchar(255), columnname varchar(50)) 
BEGIN 
DECLARE cursor_end CONDITION FOR SQLSTATE '02000'; 
DECLARE v_column_val VARCHAR(50); 
DECLARE done INT DEFAULT 0; 
DECLARE cur_table CURSOR FOR SELECT * FROM test_prepare_vw; 
DECLARE CONTINUE HANDLER FOR cursor_end SET done = 1; 

SET @query = CONCAT('CREATE VIEW test_prepare_vw as select ', columnname, ' from ', tablename); 
select @query; 
PREPARE stmt from @query; 
EXECUTE stmt; 
DEALLOCATE PREPARE stmt; 

OPEN cur_table; 
FETCH cur_table INTO v_column_val; 
WHILE done = 0 DO 
SELECT v_column_val; 
FETCH cur_table INTO v_column_val; 
END WHILE; 
CLOSE cur_table; 

DROP VIEW test_prepare_vw; 

END; 
// 

DELIMITER ;