2008-11-05 6 views
21

Puis-je savoir quand la dernière instruction INSERT, UPDATE ou DELETE a été exécutée sur une table dans une base de données Oracle et si oui, comment?Comment savoir quand une table Oracle a été mise à jour la dernière fois

Un peu d'information: La version Oracle est 10g. J'ai une application batch qui fonctionne régulièrement, lit les données d'une seule table Oracle et les écrit dans un fichier. Je voudrais ignorer 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", donc je ne peux pas utiliser d'administration spéciale. Edit: D'accord, "Special Admin Stuff" n'était pas exactement une bonne description. Ce que je veux dire, c'est que je ne peux rien faire d'autre que de sélectionner des tables et d'appeler des procédures stockées. Changer n'importe quoi sur 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.

+0

Oui ... le commentaire de 2010 concerne la lenteur de vos DBA? –

+0

Eh bien, en quelque sorte. Ils sont lents, mais comme je l'ai dit dans un commentaire précédent, je les comprends. S'il y a un problème avec cette base de données, c'est vraiment moche, vraiment rapide. Vous pouvez avoir des choses là-dedans, mais seulement après avoir été analysé en enfer par un tas de gens. – Maximilian

Répondre

35

Puisque vous êtes sur 10g, vous pouvez éventuellement utiliser le ORA_ROWSCN pseudo-colonne. Cela vous donne une limite supérieure du dernier SCN (numéro de changement de système) qui a provoqué un changement dans la ligne. Comme il s'agit d'une séquence croissante, vous pouvez stocker le maximum de ORA_ROWSCN que vous avez vu, puis rechercher uniquement les données avec un SCN supérieur à celui-ci. Par défaut, ORA_ROWSCN est actuellement maintenu au niveau du bloc, de sorte qu'un changement à n'importe quelle ligne dans un bloc changera 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 modification si nous parlons de modèles d'accès aux données "normaux".Vous pouvez reconstruire la table avec ROWDEPENDENCIES pour que le ORA_ROWSCN soit suivi au niveau de la ligne, ce qui vous donne des informations plus précises, mais nécessite un effort ponctuel pour reconstruire la table. Une autre option serait de configurer quelque chose comme Change Data Capture (CDC) et de faire de votre application OCI un abonné aux modifications de la table, mais cela nécessite également un effort ponctuel pour configurer CDC.

+0

Whoa, c'est vraiment cool. J'ai raté cette pseudo-colonne. mais je n'utiliserais pas CDC ... beaucoup trop complexe pour ses fins. J'utiliserais DCN (notification de changement de base de données). –

+0

Merci! Aussi très utile. – Maximilian

+1

Qu'est-ce qu'une ligne est supprimée? Comment puis-je savoir? –

1

Vous devez ajouter un déclencheur à insérer, mettre à jour, supprimer qui définit une valeur dans une autre table sysdate. Lorsque vous exécutez l'application, il lit la valeur et l'enregistre quelque part afin que la prochaine fois qu'il est exécuté, il dispose d'une référence à comparer.

Considéreriez-vous comme "Special Admin Stuff"?

Il vaudrait mieux décrire ce que vous faites pour obtenir des réponses plus claires.

5

Pourriez-vous exécuter une somme de contrôle de quelque sorte sur le résultat et le stocker localement? Puis, lorsque votre application interroge la base de données, vous pouvez comparer sa somme de contrôle et déterminer si vous devez l'importer.

Il semble que vous puissiez utiliser la fonction ORA_HASH pour ce faire.

Mise à jour: Une autre bonne ressource: 10g’s ORA_HASH function to determine if two Oracle tables’ data are equal

+0

Cela semble prometteur. Merci! – Maximilian

+0

Bonne chance :) (Je vais aussi ajouter ceci à ma "boîte à outils", donc j'ai appris quelque chose de nouveau aussi!) – mwilliams

+0

Cela semble intéressant. Pouvez-vous inclure un exemple de création d'un hachage pour une table? –

1

Combien de temps le processus de traitement par lots prendre pour écrire le fichier? Il peut être plus facile de le laisser aller et ensuite comparer le fichier avec une copie du fichier de l'exécution précédente pour voir si elles sont identiques.

+0

Voilà le problème: je n'écris pas seulement les données mais j'ai besoin de les traiter de manière compliquée. Cela prend plusieurs heures et c'est ce que j'essaie d'éviter. – Maximilian

9

Demandez à votre administrateur de base de données de vérifier. Il peut commencer un audit avec une commande simple comme:

AUDIT INSERT ON user.table 

Ensuite, vous pouvez interroger la table USER_AUDIT_OBJECT pour déterminer s'il y a eu un insert sur la table depuis la dernière exportation.

google pour l'audit Oracle pour plus d'informations ...

+1

Merci. Je suppose que c'est la façon dont il est censé être fait. Malheureusement, "demander le DBA" a tendance à être plutôt compliqué. Ils sont vraiment paranoïaques pour changer de choses. Je les comprends. Si quelque chose ne va pas avec ce DB, les choses ont tendance à être laide. – Maximilian

3

Oracle peut surveiller les tables pour les modifications et lorsqu'une modification se produit, il 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é, et le type d'action, Ins, upd, del.

Alors vous n'allez même pas à la table, vous vous asseyez et attendez d'être appelé. Vous n'irez que s'il y a des changements à écrire.

Il s'appelle Database Change Notification. C'est beaucoup plus simple que CDC, comme Justin l'a mentionné, mais les deux nécessitent des trucs d'administration sophistiqués. La bonne partie est que ni l'un ni l'autre ne nécessite de changements à l'APPLICATION. L'inconvénient est que CDC est bien pour les tables de volume élevé, DCN ne l'est pas.

+0

FWIW, J'ai récemment découvert CQN (c.-à-CDN) n'est pas pris en charge sur les PDB 12c. J'espère que ce sera dans le futur. – ddevienne

38

Je suis vraiment en retard à ce parti, mais voici comment je l'ai fait:

SELECT SCN_TO_TIMESTAMP(MAX(ora_rowscn)) from myTable; 

Il est assez proche pour mes besoins.

+4

Fonctionne depuis la dernière mise à jour de votre table il n'y a pas longtemps. Sinon vous obtenez une erreur, donc il est plus sûr d'abord de faire un: gauche rejoindre sys.smon_scn_time tiemposmax sur myTable.ora_rowscn <= tiemposmax.scn puis d'appliquer SCN_TO_TIMESTAMP à votre ora_rowscn table si et seulement s'il y a une correspondance.Sinon, vous pouvez afficher SCN_TO_TIMESTAMP (MIN (SCN)) à partir de sys.smon_scn_time en tant que première date à laquelle la table a été modifiée auparavant. –

-3

S'il vous plaît utiliser la déclaration ci-dessous

select * from all_objects ao where ao.OBJECT_TYPE = 'TABLE' and ao.OWNER = 'YOUR_SCHEMA_NAME' 
+0

-1: Cela ne répond pas à la question. –

+0

vous avez adressé la question à la direction différente –

6
SELECT * FROM all_tab_modifications; 
+0

Cela vous obligerait à recueillir des statistiques sur la table en premier, car il montre seulement les changements après les dernières statistiques de collecte. – Superdooperhero

0

Si quelqu'un cherche toujours une réponse qu'ils peuvent utiliser Oracle Database Change Notification fonctionnalité à venir avec Oracle 10g. Il nécessite le privilège système CHANGE NOTIFICATION. Vous pouvez enregistrer les écouteurs quand déclencher une notification à l'application.

Questions connexes