2013-11-06 3 views
0

У меня есть база данных Oracle, и я пытаюсь программно определить, имеет ли представление столько же записей, сколько и таблицы, из которых он извлекает. Это может быть не так, потому что представление может ошибочно запрашивать таблицы в другой схеме. Сначала я пытался делатьУсловия Oracle Race при выполнении select select select и insert

select count(*) from view 

затем делает

select count(*) from 
(select * from table1 
union 
select * from table2) 

и сравнение результатов.

Проблема в том, что я беспокоюсь о том, что кто-то делает вставку, скажем, table2 за время между моим первым запросом и моей второй. В этом случае я, возможно, получил 5 записей из представления, но после завершения вставки я могу получить 6 записей из второго запроса.

Я не хочу, чтобы ложно сообщить о проблеме, так что я думал о выполнении объединения двух запросов:

select count(*) from view 
union 
select count(*) from 
(select * from table1 
union select * from table2) 

Но я не знаю, будет ли это на самом деле предотвратить вставку, которая происходит между запрос к представлению и запрос к объединению таблиц.

В принципе, мне нужно знать, делает ли Oracle два выбора в моментальном снимке данных или если данные являются динамическими.

ответ

2

Один оператор SQL в Oracle всегда видит данные, которые существовали в определенном SCN (номер смены системы). Предполагая, что уровень изоляции транзакции по умолчанию для чтения был зафиксирован, это будет SCN при запуске запроса. Поэтому, предполагая чистый SQL, обе стороны от UNION будут определяться по данным SCN при запуске запроса.

Предостережение здесь было бы, если в представлении содержится вызов PL/SQL (т. Е. Вызов функции, который используется для определения того, включать ли конкретную строку). Запросы в блоке PL/SQL будут рассматривать текущее состояние данных, не обязательно состояние, в котором оно было, когда запрос запущен.

Если вы действительно только заботиться о количестве возвращенных строк, а не фактические данные, казалось бы, более логично было бы сделать что-то вроде

SELECT (SELECT COUNT(*) cnt FROM view) - 
     (SELECT COUNT(*) cnt FROM table) num_diffs 
    FROM dual 

Если вы действительно хотите, чтобы сравнить данные

SELECT <<columns>> 
    FROM table 
MINUS 
SELECT <<columns>> 
    FROM view 

покажет вам данные из таблицы, которая не существует i

Смежные вопросы