首页 > 解决方案 > PL/SQL 块中的更新给出 PLS-00103 错误

问题描述

我正在尝试在另一个表的基础上创建一个块来更新一个新表中的PL/SQL一个空列。表上的字段匹配,并且没有在中没有对应行的行。我基于状态列的更新,但不是“是”和“否”,而是需要将其反映为“Y”和“N”:is_truecreated_tabletable1idcreated_tabletable1table1

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

我该怎么做才能让它发挥作用?

标签: plsql

解决方案


您的代码有多个错误:

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

你的块中也没有 ,所以实际上它与运行正常的.COMMITPL/SQLSQL


根据您描述的情况,我对代码块进行了一些更改。这将限制在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;

推荐阅读