plsql - PL/SQL 块中的更新给出 PLS-00103 错误
问题描述
我正在尝试在另一个表的基础上创建一个块来更新一个新表中的PL/SQL
一个空列。表上的字段匹配,并且没有在中没有对应行的行。我基于状态列的更新,但不是“是”和“否”,而是需要将其反映为“Y”和“N”:is_true
created_table
table1
id
created_table
table1
table1
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_table
非常大,我正在尝试使用一个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
我该怎么做才能让它发挥作用?
解决方案
您的代码有多个错误:
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:
/
thePLS-00103
实际上只是告诉您/
缺少 a 。之后剩余的错误是PLS-00302: component 'ROWNUM' must be declared
. 来自“Oracle 数据库在线文档”:rownum 是一个伪列。
您将在第一次遇到being时将表设置中的每一行SQL
更新为,因为您没有给它一个子句。我假设这不是你的意图。is_true
'Y'
status
'Yes'
WHERE
你的块中也没有 ,所以实际上它与运行正常的.COMMIT
PL/SQL
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;
/
这将一次性更新所有行,仍然只更新“空”行:
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;
推荐阅读
- node.js - 使用 Node WKHTMLTOPDF 将页面添加到 PDF
- excel-formula - 按分隔值公式拆分单元格(excel)
- angular - 仅在外部单击时调用函数不能按预期工作
- c# - 使用个人帐户托管的 Blazor Asp.Net Core 未部署
- python - Python Shapely 似乎为多边形分配了错误的点
- bluetooth - 当我的树莓派通过蓝牙连接到安卓手机时,如何更改识别的内容?
- excel - Excel VBA - 使用 if 条件循环填充列表框
- python - 我收到导入错误:Python 中没有名为 ecommerce.shipping 的模块
- python-2.7 - ImportError:没有名为 Games.Table 的模块
- .net-core - 由于 IOException 与服务器的连接中断:无法从传输连接中读取数据: