Plsql PL/SQL块中的更新导致PLS-00103错误
我试图创建一个Plsql PL/SQL块中的更新导致PLS-00103错误,plsql,Plsql,我试图创建一个PL/SQL块来更新一个空列,is\u true,在另一个表table 1的基础上创建一个新表table。表上的id字段匹配,并且创建的表中没有行在表1中没有对应的行。我将更新基于表1的状态列,但我需要将其反映为“Y”和“N”,而不是“是”和“否”: created_table: expected results: id | is_true | other columns id | is_true | other
PL/SQL
块来更新一个空列,is\u true
,在另一个表table 1
的基础上创建一个新表table
。表上的id
字段匹配,并且创建的表中没有行在表1
中没有对应的行。我将更新基于表1的状态列,但我需要将其反映为“Y”和“N”,而不是“是”和“否”:
created_table: expected results:
id | is_true | other columns id | is_true | other columns
---|---------|-------------- ---|---------|--------------
1 | null | ... 1 | 'Y' | ...
2 | null | ... 2 | 'N' | ...
table1:
id | status | other columns
---|--------|--------------
1 | 'Yes' | ...
2 | 'No' | ...
由于created\u表
非常大,所以我尝试使用PL/SQL
过程来更新它,以便在中途出现故障时,仍然可以更新行。然后,该过程的下一次运行可以在不处理已处理的行的情况下拾取以前失败的位置
我已尝试使用此代码块进行测试:
DECLARE
is_true varchar2 (5) created_table.is_true%type;
BEGIN
FOR status IN (SELECT a.status
from table1 a
left join created_table b
where and a.id=b.id )
LOOP
IF status = 'Yes' THEN
UPDATE created_table SET is_true= 'Y'
ELSE
UPDATE created_table SET is_true= 'N'
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:
* & = - + ; < / > at in is mod remainder not rem
PLS-00103:在预期以下情况之一时遇到符号“文件结束”:
* & = - + ; < / > at in是mod余数而不是rem
我该怎么做才能使它工作?您的代码有多个错误:
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:必须声明组件“ROWNUM”
。来自“Oracle数据库联机文档”:
您的SQL
将在第一次遇到状态为'Yes'
时将表设置中的每一行更新为'Y'
,因为您没有给它一个WHERE
子句。我想这不是你的意图
在PL/SQL
块中也有noCOMMIT
,因此实际上它与运行正常的SQL
相同
根据您描述的情况,我对代码块做了一些更改。这将提供在提交之前可以处理多少行的限制。我把上限定为5。你应该把它改成合适的。对于是否为真
,它不会拾取任何具有空值的行,因此实际上它只对未处理的行起作用:
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;
/
似乎不是一个真正的专栏。当a
中没有id
的记录存在于创建的\u表中时,会发生什么情况?您似乎对SQL
和pl/SQL
的使用有点困惑。你能用语言更好地表达你想通过一个例子实现的目标吗?另外,是否有必要在pl/sql过程中使用光标
,或者一个sql
就足够了?感谢您的回答。我们的方法是使用相关数据集创建一个表,并使用状态标志的附加列更改该表。下一步是我要做的事情——我们正试图根据另一个表中特定列的值设置标志,并在其中确保如果该过程失败,它将不会拾取已处理的记录。如果您的问题没有更多信息,我认为任何人都无法帮到您。我不想猜测,然后发布一个不适用于这种情况的答案。我已经编辑了我的回复。感谢回复。我们的方法是使用相关数据集创建一个表,并使用状态标志的附加列更改该表。下一步是我一直在做的事情-我们正试图根据另一个表中特定列的值设置标志,并在其中确保如果进程失败,它不会拾取已处理的记录。也许可以这样想:您需要什么完整的信息才能使程序工作,如果实际代码没有问题?我不知道“拾起”是什么意思。这是指提交已处理的行还是回滚?请更新问题,因为信息往往会在评论中丢失,并且当人们对问题感到困惑时,您不太可能获得帮助。这是我的桌子,这是我的另一张桌子。我想让这一切发生。这些都是特殊情况。这是我的密码。这是错误或这是错误的结果。
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;