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

Renvoyer des lignes de données à partir d'un bloc pl/sql

Un bloc anonyme ne peut rien renvoyer. Vous pouvez affecter des valeurs à une variable de liaison, y compris un type de collection ou un curseur de référence, à l'intérieur du bloc. Mais la collection devrait être définie, ainsi que déclarée, en dehors du bloc. Autrement dit, il devrait s'agir d'un type que vous pouvez utiliser en SQL brut, et non d'un type défini en PL/SQL. Pour le moment, vous utilisez un type PL/SQL qui est défini dans le bloc, et une variable qui est également déclarée dans le bloc - donc c'est hors de portée pour le client, et ne serait pas un type valide en dehors non plus . (Il n'a pas non plus besoin d'être initialisé, mais c'est un problème mineur).

Selon la façon dont il sera réellement consommé, une option consiste à utiliser un curseur de référence, et vous pouvez le déclarer et l'afficher via SQL*Plus ou SQL Developer avec la variable et print commandes. Par exemple :

variable rc sys_refcursor

begin
  open :rc for ( select ... /* your cursor statement */ );
end;
/

print rc

Vous pouvez faire quelque chose de similaire à partir d'une application cliente, par ex. avoir une fonction renvoyant un curseur de référence ou une procédure avec un paramètre de sortie qui est un curseur de référence, et le lier à partir de l'application. Ensuite, parcourez le curseur de référence en tant que jeu de résultats. Mais les détails dépendent de la langue utilisée par votre application.

Une autre option consiste à avoir une fonction en pipeline qui renvoie un type de table - à nouveau défini au niveau SQL (avec create type ) pas en PL/SQL - ce qui peut consommer moins de ressources qu'une collection renvoyée en une seule fois.

Mais je dois me demander pourquoi tu fais ça. Vous avez dit que "creuser pour les lots ultérieurs prend beaucoup plus de temps", ce qui donne l'impression que vous utilisez un mécanisme de pagination dans votre requête, en générant un numéro de ligne, puis en sélectionnant une plage de 100 à l'intérieur de celle-ci. Si votre client/application veut obtenir toutes les lignes, il serait plus simple d'avoir une seule exécution de requête mais récupérer le jeu de résultats par lots.

Malheureusement, sans aucune information sur l'application, ce ne sont que des spéculations...