2008-11-05 18 views
21

Czy mogę dowiedzieć się, kiedy wykonano ostatnią instrukcję INSERT, UPDATE lub DELETE w tabeli w bazie danych Oracle, a jeśli tak, to w jaki sposób?Jak sprawdzić, czy tabela Oracle została zaktualizowana po raz ostatni?

Małe tło: wersja Oracle to 10g. Mam aplikację wsadową, która działa regularnie, odczytuje dane z pojedynczej tabeli Oracle i zapisuje je w pliku. Chciałbym to pominąć, jeśli dane nie uległy zmianie od czasu ostatniego wykonania zadania.

Aplikacja jest napisana w języku C++ i komunikuje się z firmą Oracle za pośrednictwem OCI. Loguje się do Oracle z "normalnym" użytkownikiem, więc nie mogę używać żadnych specjalnych zadań administratora.

Edycja: Okay, "Special Admin Stuff" nie był dokładnie dobrym opisem. Chodzi mi o to, że: nie mogę nic zrobić, oprócz WYBORU z tabel i wywoływania procedur przechowywanych. Zmiana cokolwiek na temat samej bazy danych (np. Dodawanie wyzwalaczy), niestety nie jest opcją, jeśli chcesz ją wykonać przed 2010 rok.

+0

Tak ... komentarz z 2010 roku dotyczy powolności Twoich DBA, które biorę? –

+0

Cóż, trochę. Są powolne, ale jak już wspomniałem we wcześniejszym komentarzu, rozumiem je. Jeśli jest problem z tą bazą danych, staje się naprawdę brzydki, naprawdę szybki. Możesz tam dostać rzeczy, ale tylko po tym, jak kilka osób przeanalizowało je do piekła. – Maximilian

Odpowiedz

35

Skoro jesteś na 10g, można potencjalnie wykorzystać ORA_ROWSCN pseudocolumn. To daje górną granicę ostatniego numeru SCN (numer zmiany systemu), który spowodował zmianę w wierszu. Ponieważ jest to sekwencja rosnąca, możesz zapisać maksymalnie, który widziałeś, a następnie szukać tylko danych o numerze SCN większym.

Domyślnie ORA_ROWSCN jest rzeczywiście utrzymywany na poziomie bloku, więc zmiana dowolnego wiersza w bloku zmieni ORA_ROWSCN dla wszystkich wierszy w bloku. Jest to prawdopodobnie wystarczające, jeśli celem jest zminimalizowanie liczby wierszy przetwarzanych wielokrotnie bez żadnych zmian, jeśli mówimy o "normalnych" wzorcach dostępu do danych.Możesz odbudować tabelę za pomocą ROWDEPENDENCIES, co spowoduje śledzenie ORA_ROWSCN na poziomie wiersza, co daje bardziej szczegółowe informacje, ale wymaga jednorazowej próby odbudowania tabeli.

Inną opcją byłoby skonfigurowanie czegoś w rodzaju zmiany danych przechwytywania (CDC) i uczynienie aplikacji OCI subskrybentem zmian w tabeli, ale to również wymaga jednorazowej próby skonfigurowania CDC.

+0

Whoa, to naprawdę fajne. Tęskniłem za tą pseudokolumną. ale nie używałbym CDC ... zbyt skomplikowanego dla jego celów. Korzystałbym z DCN (powiadomienie o zmianie bazy danych). –

+0

Dzięki! Również bardzo pomocne. – Maximilian

+1

Co to jest wiersz usunięty? Jak mogę się dowiedzieć? –

1

Musisz dodać wyzwalacz przy wstawianiu, aktualizowaniu, usuwaniu, który ustawia wartość w innej tabeli sysdate.

Po uruchomieniu aplikacji odczytuje wartość i zapisuje ją gdzieś, aby przy następnym uruchomieniu miała odniesienie do porównania.

Czy uważasz, że "specjalne elementy administracyjne"?

Lepiej byłoby opisać, co tak naprawdę robisz, aby uzyskać jaśniejsze odpowiedzi.

5

Czy można uruchomić sumę kontrolną na wynik i przechowywać lokalnie? Następnie, gdy aplikacja wysyła zapytania do bazy danych, można porównać jej sumę kontrolną i ustalić, czy należy ją zaimportować?

Wygląda na to, że można w tym celu użyć funkcji ORA_HASH.

Aktualizacja: Innym dobrym źródłem: 10g’s ORA_HASH function to determine if two Oracle tables’ data are equal

+0

To wygląda obiecująco. Dzięki! – Maximilian

+0

Powodzenia :) (Dodam to również do mojego "skrzynki narzędziowej", więc nauczyłem się też czegoś nowego!) – mwilliams

+0

Brzmi interesująco. Czy możesz dołączyć przykład tworzenia skrótu do tabeli? –

1

Jak długo trwa proces wsadowy podjąć, aby zapisać plik? Najłatwiej jest pozwolić mu iść dalej, a następnie porównać plik z kopią pliku z poprzedniego uruchomienia, aby sprawdzić, czy są identyczne.

+0

To jest problem: nie tylko piszę dane, ale muszę je przetwarzać w skomplikowany sposób. To zajmuje kilka godzin i tego staram się uniknąć. – Maximilian

9

Zapytaj administratora DBA o audyt. On może rozpocząć kontrolę z prostym poleceniem:

AUDIT INSERT ON user.table 

Następnie można kwerendy USER_AUDIT_OBJECT tabeli aby ustalić, czy doszło wkładkę na stole od ostatniego eksportu.

google for Oracle badania o więcej informacji ...

+1

Dzięki. Sądzę, że tak właśnie należy postąpić. Niestety, "Zadawanie DBA" zwykle jest dość skomplikowane. Oni są naprawdę paranoiści o zmianie rzeczy. Rozumiem je. Jeśli coś jest nie tak z tym db, rzeczy wydają się brzydkie. – Maximilian

3

Oracle może oglądać tabele zmian, a gdy wystąpi zmiana, może wywoływać funkcję zwrotną w PL/SQL lub OCI. Callback otrzymuje obiekt będący zbiorem tabel, które uległy zmianie, i który zawiera kolekcję rowid, która uległa zmianie, oraz typ działania, Ins, upd, del.

Więc nawet nie idziesz do stołu, siedzisz i czekasz na telefon. Pójdziesz tylko, jeśli są jakieś zmiany do napisania.

Nazywa się Database Change Notification. Jest o wiele prostsze niż CDC, o czym wspomniał Justin, ale oba wymagają pewnych wymyślnych zadań administratora. Dobrą częścią jest to, że żadna z nich nie wymaga zmian w APLIKACJI.

Ograniczeniem jest to, że CDC jest w porządku dla tabel o dużej objętości, a DCN nie.

+0

FWIW, Ostatnio odkryłem, że CQN (czyli CDN) nie jest obsługiwany na PDB 12c. Mam nadzieję, że będzie w przyszłości. – ddevienne

38

Jestem bardzo późno do tej partii, ale oto jak to zrobiłem:

SELECT SCN_TO_TIMESTAMP(MAX(ora_rowscn)) from myTable; 

Jest wystarczająco blisko do moich celów.

+4

Działa tak długo, jak ostatnia aktualizacja tabeli nie była zbyt dawno temu. W przeciwnym razie jest to najbezpieczniejsze, aby najpierw wykonać: pozostawić dołączyć sys.smon_scn_time tiemposmax na myTable.ora_rowscn <= tiemposmax.scn , a następnie zastosować SCN_TO_TIMESTAMP do ora_rowscn tabeli tylko wtedy, gdy jest dopasowanie.W przeciwnym razie możesz wyświetlić SCN_TO_TIMESTAMP (MIN (SCN)) z sys.smon_scn_time jako najwcześniejszą datę wcześniejszej modyfikacji tabeli. –

-3

skorzystaj z poniższego komunikat

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

-1: Nie dotyczy to pytania. –

+0

skierowałeś pytanie do innego kierunku –

6
SELECT * FROM all_tab_modifications; 
+0

Wymagałoby to zebrania statystyk na stole, ponieważ pokazuje tylko zmiany po ostatniej statystyce zebrania. – Superdooperhero

0

Jeśli ktoś wciąż szuka odpowiedzi mogą wykorzystać Oracle Database Change Notification cecha pochodzących z Oracle 10g. Wymaga to uprawnień systemowych CHANGE NOTIFICATION. Możesz zarejestrować słuchaczy, kiedy wywołać powiadomienie z powrotem do aplikacji.

Powiązane problemy