2013-02-13 3 views
0

У меня есть следующий запросOracle 11g PL/SQL курсор, пересекаться запрос

select distinct name from table1 
intersect 
select distinct name from table2; 

я загружаю ResultSet в курсор в процедуре PL/SQL, например:

cursor c1 is (select distinct name from table1 
intersect 
select distinct name from table2); 

Для некоторых причина последнего значения в наборе результатов дублируется в курсоре. Этого не происходит при выполнении запроса самостоятельно. Есть идеи, почему это происходит?

Код для цикла:

var table.col%type; 

BEGIN 
OPEN c1; 
LOOP  
BEGIN 
    exit when c1%NOTFOUND; 
    FETCH c1 into var;  
    INSERT INTO table values (col1, var); 
    commit; 
EXCEPTION 
WHEN DUP_VAL_ON_INDEX THEN   
CONTINUE; 
END; 
END LOOP;  
END; 
+0

это операция набора SQL, которая выбирает только общие элементы из двух разных операторов SELECT. – user2001117

+3

Как вы выполняете цикл на курсоре? можете ли вы показать нам какой-то код? –

+0

Циклический код добавлен в вопрос. Когда я запрашиваю таблицу, в которую данные вставляются, после запуска процедуры последнее значение вставляется дважды. – sotn

ответ

2

EXIT WHEN .. пункт должен прийти после FETCH.

Предположим, у вашего курсора было 10 записей, чтобы вернуться. Перед началом первой выборки %NOTFOUND оценивается до NULL, и обработка переходит к следующему оператору, который равен FETCH в вашем случае. Теперь, если мы перейдем к 10-й итерации, FETCH получит 10-ю запись, и она будет вставлена ​​в таблицу назначения. Цикл будет двигаться вперед, а так как ваш EXIT WHEN %NOTFOUND находится перед выборкой, он по-прежнему имеет значение с последней итерации, и он позволяет управлять движением вперед, и там, fetch не сможет получить какую-либо запись, но код будет в любом случае вставлен последняя строка, полученная на 10-й итерации. Теперь в следующем цикле, c1%NOTFOUND будет оцениваться в TRUE и цикл завершится

var table.col%type; 

BEGIN 
OPEN c1; 
LOOP  
BEGIN 

FETCH c1 into var;  
exit when c1%NOTFOUND;  
INSERT INTO table values (col1, var); 
commit; 
EXCEPTION 
WHEN DUP_VAL_ON_INDEX THEN   
CONTINUE; 
END; 
END LOOP;  
END; 
-2

Это характерно для задач, которые вы видите с явными курсорами.

Ваш первый выбор должен быть единственным оператором SQL, не более того.

Если вам нужно было использовать курсор, вы должны использовать неявное, где это возможно.

+1

-1 Это не проблема с явными курсорами, это связано с тем, как используется явный курсор. Согласившись с настроением, «первый выбор должен быть единственным заявлением SQL». –

+0

Любая техника может использоваться хорошо или плохо, Джеффри и явные курсоры не являются исключением. По сравнению с неявными курсорами им требуется больше логики, больше кода, они во многих случаях медленнее, и они всегда более склонны к ошибкам кодирования. Даже хорошо написанный явный курсор, как правило, медленнее и уступает неявному курсору. http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1205168148688 –

+0

У меня нет споров с этим; но ваш пост не является ответом на вопрос («почему это происходит»), это было бы более уместно в качестве комментария. –

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