В вашем коде было несколько ошибок:
DECLARE
-- is_true varchar2 (5) created_table.is_true%type; -- PLS-00103: Encountered the symbol "CREATED_TABLE" when expecting one of the following:
is_true created_table.is_true%type;
BEGIN
FOR status IN (SELECT a.status
from table1 a
-- left join created_table b -- ORA-00905: missing keyword
-- where and a.id=b.id )
left join created_table b on a.id = b.id)
LOOP
-- IF status = 'Yes' THEN -- PLS-00306: wrong number or types of arguments in call to '='
IF status.status = 'Yes' THEN
-- UPDATE created_table SET is_true= 'Y' -- ORA-00933: SQL command not properly ended
UPDATE created_table SET is_true= 'Y';
ELSE
UPDATE created_table SET is_true= 'N'
-- WHERE ROWNUM := status.ROWNUM -- ORA-00920: invalid relational operator and ORA-00933: SQL command not properly ended
WHERE ROWNUM = status.ROWNUM;
END IF;
DBMS_OUTPUT.PUT_LINE('Done');
END LOOP;
END; -- PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
/
PLS-00103
на самом деле просто говорит вам, что /
отсутствует. После этого оставшаяся ошибка - PLS-00302: component 'ROWNUM' must be declared
. Из "Oracle База данных онлайновой документации": rownum - псевдостолбец .
Ваш SQL
будет обновлять каждую строку в настройке таблицы is_true
до 'Y'
при первом столкновении status
, являющемся 'Yes'
, поскольку вы не дали это WHERE
пункт. Я предполагаю, что это не ваше намерение.
В вашем блоке PL/SQL
также было нет COMMIT
, так что в действительности это было бы так же, как и обычный SQL
.
Исходя из описанной вами ситуации, я внес некоторые изменения в блок кода. Это обеспечит ограничение на количество строк, которые могут быть обработаны до COMMIT
. Я установил лимит на 5. Вы должны изменить это на что-то подходящее. Он не будет подбирать строки с пустыми значениями для is_true
, поэтому он будет работать только с необработанными строками:
DECLARE
commit_counter PLS_INTEGER := 1; -- count commits
commit_limit PLS_INTEGER := 5; -- rows for commit limit
counter PLS_INTEGER := commit_limit;
BEGIN
FOR rec IN (SELECT a.status, a.id
FROM created_table b
JOIN table1 a ON a.id = b.id
WHERE b.is_true IS NULL) -- do not pick up processed rows
LOOP
IF rec.status = 'Yes' THEN
UPDATE created_table SET is_true = 'Y'
WHERE id = rec.id;
ELSE
UPDATE created_table SET is_true = 'N'
WHERE id = rec.id;
END IF;
counter := counter - 1;
IF counter < 1 THEN
counter := commit_limit; --reset counter
commit_counter := commit_counter + 1;
COMMIT;
END IF;
END LOOP;
COMMIT; -- all rows are processed;
DBMS_OUTPUT.PUT_LINE(commit_counter || ' COMMITS');
END;
/
Это обновит все строки в одной go, все еще обновляются только «пустые» строки:
UPDATE created_table b
SET is_true = (SELECT CASE a.status WHEN 'Yes' THEN 'Y'
ELSE 'N'
END
FROM table1 a
WHERE a.id = b.id)
WHERE b.is_true IS NULL;