Mysql
 sql >> Base de données >  >> RDS >> Mysql

Travailler avec des curseurs SQL

Dans SQL, les curseurs servent de pointeur qui permet au langage de programmation d'application de traiter les résultats de la requête une ligne à la fois. Cet article explore rapidement le concept sous-jacent et montre comment déclarer des curseurs, les ouvrir, en récupérer des données, puis les fermer.

Curseurs SQL

Les données en base de données relationnelles sont gérées sous forme d'ensembles. Par conséquent, les résultats de requête renvoyés par les instructions SQL SELECT sont appelés ensembles de résultats. Les ensembles de résultats ne sont rien d'autre que des combinaisons d'une ou plusieurs lignes et colonnes extraites d'une ou plusieurs tables. Vous pouvez faire défiler les ensembles de résultats pour extraire les informations dont vous avez besoin. Les éléments de données renvoyés sont utilisés par des langages de programmation tels que Java ou tout autre à des fins d'application spécifiques. Mais c'est là que réside le problème de inadéquation d'impédance en raison de la différence de construction entre le modèle de base de données et le modèle de langage de programmation.

Un modèle de base de données SQL a trois constructions principales :

  • les colonnes (ou attributs) et leurs types de données
  • lignes (enregistrements ou tuples)
  • tableaux (collection d'enregistrements)

Par conséquent, les incompatibilités principales entre deux modèles sont :

  1. Les types de données d'attribut disponibles dans le modèle de base de données ne sont pas les mêmes que les types de variables utilisés dans les langages de programmation. Il existe de nombreux langages hôtes, et chacun a un type de données différent. Par exemple, les types de données C/C++ et Java sont différents, tout comme les types de données SQL. Par conséquent, un mécanisme contraignant est nécessaire pour atténuer le problème d'incompatibilité.
  2. Le résultat renvoyé par les instructions SQL SELECT sont des multi-ensembles d'enregistrements où chaque enregistrement est une collection d'attributs. Les langages de programmation hôtes fonctionnent généralement sur des valeurs de données individuelles de tuple renvoyées par la requête. Par conséquent, il est essentiel que le résultat de la requête SQL corresponde à la structure de données prise en charge par le langage de programmation. Le mécanisme de bouclage sur les tuples est nécessaire pour parcourir les tuples et leurs valeurs d'attribut.

Le curseur agit comme une variable d'itérateur pour boucler sur les tuples renvoyés par la requête SQL et extraire des valeurs individuelles dans chaque tuple qui peuvent ensuite être mappées au type approprié de variables de programme.

Le curseur sert donc de pointeur qui permet au langage de programmation de traiter le résultat de la requête un enregistrement à la fois. Un curseur peut parcourir toutes les lignes d'un résultat de requête en se concentrant sur une ligne à la fois. Considérez la requête SQL suivante :

SELECT emp_no, first_name, last_name, birth_date
FROM employees
WHERE MONTH(birth_date) = MONTH(CURRENT_DATE)
AND DAY(birth_date) = DAY(CURRENT_DATE);

Le résultat de la requête de l'instruction ci-dessus renvoie les détails de tous les employés dont la date de naissance tombe le jour en cours d'un mois particulier. Le résultat peut contenir plusieurs lignes, mais le langage de l'application hôte ne peut traiter qu'une seule ligne à la fois. Par conséquent, le curseur est déclaré en tant qu'instruction SQL intégrée dans le langage de programmation d'application. Le curseur est alors ouvert un peu comme un fichier et extrait une seule ligne du résultat de la requête. Les autres lignes sont extraites par la suite, dans l'ordre jusqu'à la fermeture du curseur.

Déclarer un curseur

Les curseurs sont déclarés un peu comme une variable. Un nom est donné, il y a des instructions pour ouvrir le curseur, récupérer le résultat de la requête et enfin fermer le curseur. Notez que différentes implémentations SQL prennent en charge l'utilisation des curseurs d'une manière différente. Mais il existe un accord général sur la façon dont le curseur doit être écrit.

Nous devons utiliser des instructions SQL pour implémenter pleinement la fonctionnalité du curseur, car la simple déclaration d'un curseur ne suffit pas pour extraire des données d'une base de données SQL. Il y a quatre étapes de base pour déclarer un curseur :

DÉCLARER LE CURSEUR : La déclaration commence en donnant un nom au curseur et en affectant l'expression de requête à invoquer lorsque le curseur est ouvert.

OUVRIR : L'instruction open exécute l'expression de requête assignée et prépare le résultat de la requête pour FETCH suivant.

RÉCUPÉRER : Récupère les valeurs de données dans des variables qui peuvent ensuite être transmises au langage de programmation hôte ou à d'autres instructions SQL intégrées.

FERMER : Le curseur est fermé et ne récupère plus aucun résultat de requête.

La syntaxe est la suivante :

DECLARE <cursor_name>
[SENSITIVE | INSENSITIVE | ASENSITIVE]
[SCROLL | NO SCROLL] CURSOR
[ WITH HOLD | WITHOUT HOLD]
[ WITH RETURN | WITHOUT RETURN]
FOR <sql_query_expression>
[ ORDER BY <sort_expression>]
[ FOR {READ ONLY | UPDATE [ OF <list_of_column>]}]

La partie essentielle d'une déclaration de curseur est la suivante :

 DECLARE <cursor_name> FOR <sql_query_expression>

La partie facultative telle que [SENSITIVE | INSENSIBLE | ASENSITIVE] indique si le curseur est sensible aux modifications et s'il doit les refléter dans le résultat de la requête. SENSIBLE signifie que le curseur est affecté par les modifications, INSENSIBLE signifie que le curseur n'est pas affecté et ASENSIBLE signifie que les modifications peuvent ou non être visibles pour le curseur. S'il n'est pas spécifié, il suppose l'option ASENSITIF.

L'option [SCROLL | NOSCROLL] définit la capacité de défilement du curseur. S'il n'est pas spécifié, il suppose l'option NO SCROLL.

L'option [ WITH HOLD | WITHOUT HOLD] définit s'il faut suspendre ou fermer automatiquement lorsque la transaction due au curseur est validée. S'il n'est pas spécifié, il conserve l'option SANS MAINTIEN.

L'option [ AVEC RETOUR | SANS RETOUR] détermine s'il faut renvoyer le jeu de résultats du curseur à l'invocateur, tel qu'une autre routine SQL ou un autre langage hôte. Si non spécifié, cela signifie SANS RETOUR.

La clause ORDER BY est utilisée pour trier le résultat de la requête renvoyé selon la technique de tri spécifiée.

L'option UPDATE fait référence à l'utilisation de l'instruction UPDATE ou DELETE en association avec les lignes renvoyées par l'instruction SELECT du curseur. Une telle modification n'est pas possible si nous spécifions l'option READ ONLY. Si elle n'est pas spécifiée, l'option UPDATE est utilisée par défaut.

Par conséquent, un curseur simple peut être déclaré comme suit :

DECLARE mycursor CURSOR
 FOR
SELECT emp_no, first_name, last_name, birth_date
  FROM employees
 WHERE MONTH(birth_date) = MONTH(CURRENT_DATE)
  AND DAY(birth_date) = DAY(CURRENT_DATE);

Curseurs dans MySQL

Généralement, il existe deux types de curseurs dans MySQL :les curseurs en lecture seule et les curseurs en avant uniquement. Ces curseurs peuvent être utilisés pour la procédure stockée MySQL. Ces curseurs nous aident à parcourir les résultats de la requête une ligne à la fois et à extraire des variables pour un traitement ultérieur. Il est possible de déclarer plusieurs curseurs et de les imbriquer dans des boucles. Notez que les curseurs sont en lecture seule car ils sont utilisés pour parcourir des tables temporaires. Le curseur exécute généralement la requête lorsque nous l'ouvrons.

L'un des problèmes avec les curseurs dans MySQL est qu'ils peuvent ralentir les performances de la requête en raison des opérations d'E/S supplémentaires qu'ils effectuent. Ceci est particulièrement vrai pour les vrais types de données volumineux tels que BLOB et TEXT. Comme les curseurs fonctionnent avec des tables temporaires, ces types ne sont pas pris en charge dans les tables en mémoire. Par conséquent, tout en travaillant avec ces types, MySQL doit créer des tables temporaires sur le disque et cela nécessite beaucoup d'opérations d'E/S et cela aussi dans les périphériques lents comme les disques. C'est la principale raison de la lenteur des performances du curseur.

MySQL ne prend pas non plus en charge les curseurs côté client, mais l'API client peut les émuler si nécessaire. Mais alors ce n'est pas très différent de récupérer le résultat dans un tableau dans un langage de programmation comme Java et de le manipuler à la place.

Voici un exemple sur la façon d'écrire des curseurs dans MySQL.

CREATE PROCEDURE 'cursor_demo'()
BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE id INT(11);
    DECLARE fn varchar(14);
    DECLARE ln varchar(16);
    DECLARE bdate date;
  DECLARE mycursor CURSOR FOR
  SELECT emp_no, first_name, last_name, birth_date
    FROM employees
    WHERE MONTH(birth_date)=MONTH(CURRENT_DATE)
      AND DAY(birth_date)=DAY(CURRENT_DATE);
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    OPEN mycursor;
  fetch_loop: LOOP
    FETCH mycursor INTO id, fn, ln, bdate;
  IF done THEN
      LEAVE fetch_loop;
    END IF;
    SELECT id, fn, ln, bdate;
  END LOOP;
  CLOSE mycursor;
END

Appelez la procédure est stockée comme suit :

mysql> CALL cursor_demo

La procédure récupère les lignes d'une table nommée employee dont la date de naissance correspond au jour et au mois en cours dans un curseur nommé mycursor et les imprime simplement à l'aide de l'instruction SELECT.

Reportez-vous à la documentation MySQL sur le curseur pour plus d'informations.

Conclusion

Les curseurs ne sont rien d'autre que des pointeurs vers les ensembles d'enregistrements renvoyés par la requête SQL. Le pointeur pointe généralement vers une ligne à la fois et peut être parcouru dans une boucle pour récupérer des enregistrements individuels. SQL est normalement utilisé pour une invocation directe pour accéder et créer des objets de données. Les curseurs fournissent la technique du SQL interactif où il permet l'exécution ad hoc d'instructions SQL facilitée par l'application cliente. Le mécanisme du curseur exploite le modèle d'accès aux données dans lequel les instructions SQL sont intégrées dans un langage hôte tel que C, C++ ou Java, etc. Ceci n'est qu'un aperçu de ce que le curseur est sur le point de commencer. Reportez-vous à la documentation appropriée de la base de données SQL pour plus de détails sur les normes spécifiques de diverses implémentations.

# # #