Oracle Curseur Ref Vs Sélectionnez avec la gestion des exceptions
J'ai un couple de scénarios:
- Besoin de lire la valeur d'une colonne de trois tables différentes dans un ordre prédéfini et seulement 1 table a les données
- Lire les données de la table table1 si les enregistrements sont présents pour les critères d'autre de lire les données à partir de Table2 pour un critère donné
Dans Des Procédures Stockées Oracle
La façon dont ils sont traités est d'abord à obtenir le nombre pour une requête donnée dans une variable, et si le nombre > 0, puis on exécute la même requête pour lire les données réelles comme dans:
select count(*) from table1 into v_count
if v_count > 0
then
select data into v_data from table1
end if;
Return v_data
Ceci est fait pour éviter la no_data_found exception, sinon j'aurais besoin de trois gestionnaire d'exception blocs pour attraper le no_data_found exception pour chaque accès à la table.
Actuellement, je suis de réimplémenter cette avec des Curseurs de sorte que j'ai quelque chose comme ceci:
cursor C1 is
select data from table1;
Open C1
Fetch C1 into v_data
if C1%FOUND
then
Close C1
Return v_data
End If
Je voulais savoir lequel est le mieux d'un point de vue des performances-les avec les Curseurs, ou celui qui fait un Select dans une variable et a trois no_data_found blocs d'Exception. Je ne veux pas utiliser les deux étapes de processus de requête que nous avons actuellement.
OriginalL'auteur Dinesh Manne | 2009-04-29
Vous devez vous connecter pour publier un commentaire.
Je ne sais pas pourquoi vous êtes si soucieux d'éviter l'exception? Quel est le problème avec:
Je crois que ça va faire mieux que votre autre solution, car il ne le minimum de travail pour obtenir le résultat souhaité.
Voir Comment le mauvais est ignorant Oracle DUP_VAL_ON_INDEX exception? où je le démontrer à l'aide d'exceptions effectue mieux que de compter pour voir si il n'y a aucune données.
Pas de - voir stackoverflow.com/questions/350860/... où je le démontrer à l'aide d'exceptions effectue mieux que de compter pour voir si il n'y a aucune données.
Bien sûr, quand je dis "non", je ne veux pas de important de frais généraux qui signifie qu'ils doivent être évités!
J'ai décidé que la meilleure façon était de code de ces deux approches et obtenir certains indicateurs, qui ont été intéressants, l'Un était le cusrsor approche et de l'autre exception approche. J'ai décidé de boucle 1000 fois pour le même ensemble, à L'Exception de l'approche effectuée de mauvaise à chaque itération à 1 minute, contre le Curseur Approche qui était de 9,5 Sec dans l'ensemble. C'était comme la 3ème déclaration a été consulté sur un lien de base de données. Une fois que j'ai Supprimé cette Dblink de requête, à l'exception de l'approche est plus rapide de 0,02 secondes.
OriginalL'auteur Tony Andrews
n'est PAS équivalent à
dans un environnement multi-utilisateur. Dans le premier cas, quelqu'un pourrait mettre à jour la table entre les points où vous avez à vérifier l'existence et quand vous lisez les données.
En terme de Performance, je n'ai aucune idée de ce qui est mieux, mais je sais que la première option fait deux changements de contexte pour le moteur sql et le second seulement un changement de contexte.
Je voudrais le faire de toute façon. Ne coûte pas beaucoup de lignes de source et de vos intentions sont claires.
OriginalL'auteur erikkallen
La façon dont vous êtes la manipulation scénario 1 n'est pas bonne. Non seulement êtes-vous de faire deux requêtes lorsqu'un seul suffit, mais comme Erik l'a souligné, il ouvre la possibilité de modification des données entre les deux requêtes (sauf si vous utilisez un accès en lecture seule ou transaction sérialisable).
Étant donné que vous dites que dans ce cas, les données seront exactement dans l'une des trois tables, comment à ce sujet?
Un autre "truc" que vous pouvez utiliser pour éviter l'écriture de plusieurs pas de données-trouvé gestionnaires serait:
mais je ne vois vraiment pas d'raison que c'est mieux que d'avoir trois gestionnaires d'exception.
Pour votre deuxième scénario, je pense que ce que tu veux dire, c'est qu'il y a peut être des données dans les deux tableaux et vous souhaitez utiliser les données de la table table1 s'il est présent, sinon, utiliser les données du tableau 2. De nouveau, vous pouvez le faire en une seule requête:
Le MIN de l'option qui semble raisonnable, même si je ne suis pas sûr que je vais finir par l'utiliser
OriginalL'auteur Dave Costa
Une version améliorée de "Dave Costa"'s MIN option...
Maintenant
v_rowcount
peut être vérifiée pour les valeurs 0, >1 (supérieur à 1), où la sélection normale requête jeterNO_DATA_FOUND
ouTOO_MANY_ROWS
exception. La valeur "1" indique qu'une seule ligne existe et va servir notre but.OriginalL'auteur siddagrl
OriginalL'auteur ValiTl
Utiliser le "pour la ligne du curseur" sous forme d'une boucle et la boucle sera juste pas si il n'ya pas de données:
Mon code n'a pas d'illustrer ce que je voulais dire - se sont attachés, en reformatant et en a perdu l'idée principale. Si une seule des tables de données, et l'ordre est prédéfini, alors que vous venez d'ajouter une case pour le précédent indicateur booléen avant l'exécution de la prochaine curseur de la boucle. Vous n'exécuter que de nombreux sélectionne en tant que de besoin, et ne pas avoir à gérer l'absence de données execeptions.
OriginalL'auteur dpbradley