Puis-je savoir quand la dernière instruction INSERT, UPDATE ou DELETE a été effectuée sur une table d'une base de données Oracle et si oui, comment?
Un peu de contexte: la version Oracle est 10g. J'ai une application batch qui s'exécute régulièrement, lit les données d'une seule table Oracle et les écrit dans un fichier. J'aimerais éviter cela si les données n'ont pas changé depuis la dernière exécution du travail.
L'application est écrite en C++ et communique avec Oracle via OCI. Il se connecte à Oracle avec un utilisateur "normal", je ne peux donc utiliser aucun logiciel spécial.
Edit: OK, "Stuff Admin spécial" n'était pas vraiment une bonne description. Ce que je veux dire, c'est que je ne peux rien faire en dehors de la sélection de tables et de l'appel de procédures stockées. Changer quelque chose à propos de la base de données elle-même (comme ajouter des déclencheurs) n'est malheureusement pas une option si vous voulez le faire avant 2010.
Puisque vous êtes sur 10g, vous pourriez potentiellement utiliser la pseudocolonne ORA_ROWSCN
. Cela vous donne une limite supérieure du dernier SCN (numéro de modification du système) ayant provoqué une modification de la ligne. Comme il s’agit d’une séquence de plus en plus importante, vous pouvez stocker hors du maximum ORA_ROWSCN
que vous avez vu et ne rechercher que les données avec un SCN supérieur à celui-ci.
Par défaut, ORA_ROWSCN
est en fait conservé au niveau du bloc. Par conséquent, toute modification d'une ligne d'un bloc change le ORA_ROWSCN
pour toutes les lignes du bloc. Ceci est probablement suffisant si l’intention est de minimiser le nombre de lignes que vous traitez plusieurs fois sans aucun changement si nous parlons de modèles «normaux» d’accès aux données. Vous pouvez reconstruire la table avec ROWDEPENDENCIES
, ce qui entraînera un suivi de ORA_ROWSCN
au niveau de la ligne, ce qui vous donnera des informations plus détaillées, mais nécessitera un effort ponctuel pour reconstruire la table.
Une autre option serait de configurer quelque chose comme CDC (Change Data Capture) et de faire de votre application OCI un abonné aux modifications de la table, mais cela nécessite également un effort ponctuel de configuration de CDC.
Je suis vraiment en retard pour cette soirée mais voici comment je l'ai fait:
SELECT SCN_TO_TIMESTAMP(MAX(ora_rowscn)) from myTable;
C'est assez proche pour mes besoins.
Demandez à votre administrateur de base de données sur l'audit. Il peut commencer un audit avec une simple commande comme:
AUDIT INSERT ON user.table
Vous pouvez ensuite interroger la table USER_AUDIT_OBJECT pour déterminer s'il y a eu une insertion dans votre table depuis la dernière exportation.
google pour l'audit Oracle pour plus d'informations ...
SELECT * FROM all_tab_modifications;
Pourriez-vous exécuter une somme de contrôle sur le résultat et la stocker localement? Ensuite, lorsque votre application interroge la base de données, vous pouvez comparer son total de contrôle et déterminer si vous devez l’importer.
Il semble que vous puissiez utiliser la fonction ORA_HASH pour accomplir cela.
Update: Une autre bonne ressource: La fonction ORA_HASH de 10g permet de déterminer si les données de deux tables Oracle sont égales
Oracle peut surveiller les tables des modifications et, lorsqu'une modification est apportée, peut exécuter une fonction de rappel dans PL/SQL ou OCI. Le rappel obtient un objet qui est une collection de tables qui a changé, et qui a une collection de rowid qui a changé, ainsi que le type d'action, Ins, upd, del.
Donc, vous n'allez même pas à la table, vous vous asseyez et attendez qu'on vous appelle. Vous n'irez que s'il y a des changements à écrire.
Cela s'appelle Notification de changement de base de données . C'est beaucoup plus simple que CDC, comme le mentionnait Justin, mais les deux requièrent des tâches d'administration sophistiquées. La bonne partie est qu’aucun d’eux n’exige de modification de l’APPLICATION.
La mise en garde est que CDC convient très bien pour les tables à volume élevé, pas DCN.
Combien de temps le traitement par lots prend-il pour écrire le fichier? Il peut être plus simple de le laisser aller, puis de comparer le fichier à une copie du fichier de l’exécution précédente pour voir s’ils sont identiques.
Vous devez ajouter un déclencheur lors de l'insertion, de la mise à jour et de la suppression, qui définit une valeur dans une autre table sur sysdate.
Lorsque vous exécutez l’application, il lit la valeur et l’enregistre quelque part afin que, lors de sa prochaine exécution, il dispose d’une référence à comparer.
Souhaitez-vous considérer ce "Stuff Admin spécial"?
Il serait préférable de décrire ce que vous faites réellement pour obtenir des réponses plus claires.
Si l'audit est activé sur le serveur, utilisez simplement
SELECT *
FROM ALL_TAB_MODIFICATIONS
WHERE TABLE_NAME IN ()
Si quelqu'un cherche toujours une réponse, il peut utiliser Notification de modification de base de données Oracle fonctionnalité fournie avec Oracle 10g. Il nécessite les privilèges système CHANGE NOTIFICATION
. Vous pouvez enregistrer des écouteurs quand déclencher une notification à l'application.