为什么我在更新语句后使用 RETURNING 子句时收到 "NO DATA FOUND" 异常?

Why I receive "NO DATA FOUND" exception when I use RETURNING clause after update statement?

我正在编写一个简单的 LOOP FOR 代码,以使用关联数组中填充的信息从 table 更新列。当我只使用 UPDATE 语句时,一切似乎都是正确的,但是当我添加 RETURNING 子句时,我收到 "NO DATA FOUND" 错误。谢谢!

DECLARE
  TYPE emps_info IS TABLE OF employees23%ROWTYPE
    INDEX BY PLS_INTEGER;

  t_emps_current_info emps_info;
  t_emps_new_info     emps_info;
BEGIN
  SELECT *
  BULK COLLECT INTO t_emps_current_info
  FROM   employees;

  FOR emps_index IN t_emps_current_info.FIRST .. t_emps_current_info.LAST
  LOOP
    IF
      NVL(t_emps_current_info(emps_index).commission_pct, 0) = 0 THEN
        UPDATE employees23
        SET    commission_pct = 0.3
        WHERE  employee_id = t_emps_current_info(emps_index).employee_id;
    ELSIF
      t_emps_current_info(emps_index).commission_pct BETWEEN 0.1 AND 0.3 THEN
        UPDATE employees23
        SET    commission_pct = 0.5
        WHERE  employee_id = t_emps_current_info(emps_index).employee_id;
    END IF;
  END LOOP;
END;

现在,当我添加 RETURNING 子句时,我收到以下错误:

DECLARE
  TYPE emps_info IS TABLE OF employees23%ROWTYPE
    INDEX BY PLS_INTEGER;

  t_emps_current_info emps_info;
  t_emps_new_info     emps_info;
BEGIN
  SELECT *
  BULK COLLECT INTO t_emps_current_info
  FROM   employees;

  FOR emps_index IN t_emps_current_info.FIRST .. t_emps_current_info.LAST
  LOOP
    IF
      NVL(t_emps_current_info(emps_index).commission_pct, 0) = 0 THEN
        UPDATE employees23
        SET    commission_pct = 0.3
        WHERE  employee_id = t_emps_current_info(emps_index).employee_id
        RETURNING commission_pct
        INTO      t_emps_new_info(emps_index).commission_pct;
    ELSIF
      t_emps_current_info(emps_index).commission_pct BETWEEN 0.1 AND 0.3 THEN
        UPDATE employees23
        SET    commission_pct = 0.5
        WHERE  employee_id = t_emps_current_info(emps_index).employee_id
        RETURNING commission_pct
        INTO      t_emps_new_info(emps_index).commission_pct;
    END IF;

    DBMS_OUTPUT.PUT_LINE('EMPLOYEE_ID: '                                || 
                         t_emps_current_info(emps_index).employee_id    ||
                         ' OLD COMMISSION: '                            || 
                         NVL(t_emps_current_info(emps_index).commission_pct, 0) 
                         || ' NEW COMMISSION: '                            ||
                         t_emps_new_info(emps_index).commission_pct);
  END LOOP;
END;

错误信息 - ORA-01403: 未找到数据 ORA-06512: 在第 22 行 01403.00000 - "no data found" *原因:没有从对象中找到数据。 *操作:对象中没有数据,这可能是由于提取结束。

我不确定为什么需要它,但我会将每个 UPDATE 语句 return 的值更改为一个简单的局部变量。然后我将 table 记录字段设置为简单变量。

可能不相关,但我注意到您的 ELSIF 测试没有像您的 IF 测试那样对现有 t_emps_current_info(emps_index).commission_pct 执行 NVL() .

如果是我,我会记录 IF-ELSEIF 双方的更新,看看是否一个更新有效而另一个失败。也许它只是在 ELSIF 上失败了,因为缺少 NVL()?

你得到 NO_DATA_FOUND 因为你的代码没有任何地方初始化(创建)t_emps_new_info(emps_index) 记录 - 无论何时你的代码试图分配 t_emps_new_info(emps_index).commission_pct 它都会失败。

这部分在你的代码中

DBMS_OUTPUT.PUT_LINE('EMPLOYEE_ID: '                                || 
                         t_emps_current_info(emps_index).employee_id    ||
                         ' OLD COMMISSION: '                            || 
                         NVL(t_emps_current_info(emps_index).commission_pct, 0) 
                         || ' NEW COMMISSION: '                            ||
                         t_emps_new_info(emps_index).commission_pct);

打印原始数组和返回数组。

在更新过程中的某个时间点,您的更新语句可能不会更新任何行,在这种情况下,您的原始数组将在该索引处有一个值,但您的返回数组不会

所以检查索引是否存在以避免这个错误

case when t_emps_new_info.exists(emps_index) then
 dbms_output.put_line('print something') ;
 else  dbms_output.put_line('print something else') ;
 end case;