2013-06-03 3 views
0

Когда я выполнить следующую процедуру на моем Oracle SQL DeveloperПожалуйста, отлаживать следующую процедуру ORACLE SQL

create or replace 
Procedure Table_Update 

IS 
    s_id VARCHAR2(256 byte); 

    CURSOR C1 IS 
    SELECT A.SR_ID 
    FROM TABLE_2 B,TABLE_1 A 
    WHERE A.Primary_key=B.Primary_Key; 

BEGIN 
loop 
    open c1; 
    fetch c1 into s_id; 

    exit when C1%NOTFOUND ; 

    update TABLE_2 set SR_ID = s_id;  

    commit; 

    END LOOP; 

CLOSE C1; 
END; 

table_1 и table_2 имеют аналогичные требования structure.My здесь является SR_ID от table_1 должен быть обновлен до table_2 на основе согласующего первичной key.When я запустить процедуру я получаю следующее сообщение об ошибке

Connecting to the database XXX. 
ORA-06511: PL/SQL: CURSOR ALREADY OPEN 
ORA-06512: at "Table_Update", line 7 
ORA-06512: at "Table_Update", line 13 
ORA-06512: at line 2 
PROCESS EXITED. 
Disconnecting from the database XXX. 

я попробовать это снова и снова, пожалуйста, помогите мне

Спасибо

+1

Я не эксперт, но я думаю, что youe отсутствует 'where' пункт в вашем' update' заявлении. – haki

+0

В качестве еще одного замечательного аргумента в пользу отличного ответа a_horse_with_no_name, если вы хотите сделать это таким образом, то есть у вас есть таблица строк 500 м и не можете заблокировать все это, лучше использовать BULK COLLECT и обновить ROWID, поскольку это будет быть намного быстрее. – Ben

ответ

3

Переместить open c1; за пределы цикла, вам нужно только открыть его один раз.

+0

Я попытался сделать это, создав или заменив Процедура Таблица_Update IS s_id VARCHAR2 (256 байт); CURSOR C1 IS SELECT A.SR_ID FROM TABLE_2 B, TABLE_1 A ГДЕ A.Primary_key = B.Primary_Key; открыть c1; BEGIN loop fetch c1 in s_id; выход, когда C1% NOTFOUND; обновление TABLE_2 set SR_ID = s_id; commit; END LOOP; CLOSE C1; END; Я получаю сообщение об ошибке (11,10) Элемент игнорируется, а ошибка (11,10) 'c1' должна быть типа – Sudhan

+0

@Sudhan, и результат был?прочитайте ответ a_horse_with_no_name. – Roger

+0

Может быть, вы можете увидеть мой отредактированный комментарий сейчас – Sudhan

1

Вы должны переместить open c1; перед loop
Вы открываете курсор каждый раз, когда вы идете через петлю, и вы должны только открыть курсор один раз.

подробнее http://www.techonthenet.com/oracle/cursors/

4

Как Роджер уже сказал: перемещение открытия курсора вне цикла.

Но не менее важно: не совершать внутри петля либо. Это замедляет работу, усиливает нагрузку на базу данных и также закрывает курсор.

Но что более важно: вам вообще не нужна петля. Вы можете сделать это в одном операторе обновление:

update TABLE_2 
    set SR_ID = (select a.sr_id 
       from table_1 a 
       where a.primary_key = table_2.primary_key); 

или в качестве альтернативы использовать merge заявление:

merge into table_2 
using table_1 a 
    on (table_2.primary_key = a.primary_key) 
when matched then update 
    set sr_id = a.sr_id; 

, который будет намного быстрее, чем ваш курсор на основе подхода.

Вот SQLFiddle: http://sqlfiddle.com/#!4/0b810/1

+0

+1: Или с внешним ключом из таблицы_1 в таблицу_2 в столбце первичного ключа может быть выполнено обновление против объединения двух таблиц. –

+0

+1 для альтернатив и идей. Однако я считаю, что ему нужно будет обновить только те записи, которые он намеревается, используя предложение WHERE. Это неясно, хотя OP может быть запутан. – Roger

+0

@Roger: в соответствии с вопросом OP хочет обновить все строки в таблице_2, чтобы иметь одинаковые значения в sr_id на основе первичного ключа. Я не думаю, что предложение WHERE необходимо, но оно может быть легко применено в обеих версиях. –

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