comment extraire, de supprimer, de s'engager à partir du curseur
Je suis en train de supprimer beaucoup de lignes dans une table. Je veux essayer l'approche de la mise lignes je veux supprimer dans un curseur, puis continuer à le faire, d'extraction, de supprimer, de s'engager sur chaque ligne du curseur jusqu'à ce qu'elle est vide.
Dans le code ci-dessous nous sont fetching
lignes et de les mettre dans un TYPE
.
Comment puis-je modifier le code ci-dessous pour supprimer le TYPE de l'image et tout simplement ne fetch,delete,commit
sur le curseur lui-même.
OPEN bulk_delete_dup;
LOOP
FETCH bulk_delete_dup BULK COLLECT INTO arr_inc_del LIMIT c_rows;
FORALL i IN arr_inc_del.FIRST .. arr_inc_del.LAST
DELETE FROM UIV_RESPONSE_INCOME
WHERE ROWID = arr_inc_del(i);
COMMIT;
arr_inc_del.DELETE;
EXIT WHEN bulk_delete_dup%NOTFOUND;
END LOOP;
arr_inc_del.DELETE;
CLOSE bulk_delete_dup;
- Je m'assurerais qu'un jeu basé sur la solution n'est pas une option avant d'essayer d'aller le parcours d'un curseur. Un jeu basé sur la solution sera nettement plus efficace, moins de code, et plus facile à comprendre qu'un curseur... puis-je vous demander pourquoi un standard supprimer ne fonctionne pas dans votre scénario?
- Il y a une politique qui est à mon lieu de travail. Pas une seule transaction doit être en cours d'exécution de plus de 8 secondes. C'est pourquoi je ne pouvais pas tout simplement le faire en une seule ligne de sql.
- Donc, la solution à cette douteuse de la politique, est de couper toutes les transactions en-ligne-transactions, et de sacrifier la cohérence de vos données??
- Terrible de la politique en effet.
Vous devez vous connecter pour publier un commentaire.
Pourquoi voulez-vous vous engager dans des lots? C'est seulement va ralentir votre traitement. Sauf si il y a d'autres sessions qui sont de la tentative de modifier les lignes que vous voulez supprimer, ce qui semble problématique pour d'autres raisons, l'approche la plus efficace serait de simplement supprimer les données avec un simple DELETE, c'est à dire
Bien sûr, il peut y avoir une manière plus optimale de l'écriture de cette fonction sur la façon dont la requête derrière votre curseur est conçu.
Si vous voulez vraiment éliminer la majeure partie de RECUEILLIR (ce qui va ralentir le processus sensiblement à la baisse), vous pouvez utiliser la OÙ les DE la syntaxe pour effectuer la SUPPRESSION
Être conscient, cependant, que depuis que vous avez à verrouiller la ligne (avec la clause FOR UPDATE), on ne peut pas mettre de validation dans la boucle. Faire un commit permettrait de libérer les verrous vous avait demandé, avec le POUR mise à JOUR et vous obtiendrez un ORA-01002: extraction de la séquence d'erreur
Vous ne pouvez pas obtenir une erreur d'exécution si vous supprimer le verrouillage et de éviter les, OÙ les DE la syntaxe, de la suppression de la base de données sur la valeur(s) vous avez récupéré à partir du curseur. Cependant, c'est encore de faire une extraction à travers commettre ce qui est une mauvaise pratique et augmente radicalement les chances que vous aurez, au moins de façon intermittente, obtenir un ORA-01555: instantané trop vieille erreur. Il sera aussi douloureusement lent par rapport à la seule instruction SQL ou l'essentiel de RECUEILLIR option.
Bien sûr, vous devez également vous assurer que votre processus de redémarrage dans le cas où vous traiter un sous-ensemble de lignes et avoir un certain nombre inconnu de l'intermédiaire s'engage avant le processus meurt. Si le
DELETE
est suffisante pour causer de la ligne pour ne plus être renvoyés à partir de votre curseur, votre processus est probablement déjà en mode redémarrage. Mais en général, c'est un problème si vous essayez de le briser d'une seule opération en plusieurs opérations.Un peu les choses. Il semble de votre entreprise "aucune transaction de plus de 8 secondes" de la règle (8 secondes, vous dans le Texas?), vous avez une production de db d'instance qui, traditionnellement, les applications prises en charge de faire OLTP trucs (insert 1 ligne, 2 lignes, etc), et est devenu aussi le traitement par lots db (suppression de 50% des lignes et de les remplacer avec 1mm de nouvelles lignes).
Traitement par lots doit être séparé de l'instance OLTP. Dans un traitement par lots ("données d'usine") de l'instance, je ne voudrais pas essayer de supprimer dans ce cas, je ferais probablement un DEC, drop table ancienne, renommer le nouveau tableau, reconstruire les index/stats, recompiler invalide objs approche.
En supposant que vous êtes coincé, faire du traitement par lot dans votre "8 secondes" de l'instance, vous trouverez probablement votre entreprise sera demander de plus et de plus en plus à l'avenir, afin de demander aux Administrateurs de bases de données pour autant de restauration que vous pouvez obtenir, et j'espère que vous n'obtenez pas un cliché trop vieux par l'extraction à travers engage (curseur sélectionnez la conduite de la supprime, commettent tous les 1000 lignes ou si, à supprimer à l'aide rowid).
Si les Administrateurs de base de données ne peux pas aider, vous pouvez être en mesure de d'abord créer une table temporaire contenant les rowids que vous souhaitez supprimer, puis faire une boucle par la temp de la table à supprimer de la table principale (éviter la corvée s'engage à travers), mais que votre entreprise va probablement avoir une certaine règle contre ce d'autant que c'est un autre (de base) par lot technique.
Quelque chose comme: