在第一次通话期间,我收到no_data_found错误。这是合乎逻辑的。因为表是空的。如何解决这个问题?

During the first call, I get the no_data_found error. And that is logical. Because the tables are empty. how can this be fixed?

提问人:Pitt Bear 提问时间:10/30/2023 更新时间:10/30/2023 访问量:32

问:

我尝试使用EXCEPTION,但它没有像我想要的那样工作。 对我来说,这似乎不是一个好的解决方案。

例外 当no_data_found v_current_elec_social_reading := 0;

我不知道如何以其他方式解决它。

create or replace PACKAGE BODY pkg_meter_reading IS

    PROCEDURE add_reading_e_prod IS

        v_random_e_prod                    elec_prod.power_kwh%TYPE := dbms_random.value(0, 2000);
        v_current_elec_prod_reading        elec_prod.meter_reading_kwh%TYPE;
    BEGIN


        SELECT
            meter_reading_kwh

        INTO v_current_elec_prod_reading
        FROM
            elec_prod
        ORDER BY
            date_measurement DESC
        FETCH FIRST 1 ROW ONLY;

        dbms_output.put_line(v_current_elec_prod_reading);
        INSERT INTO elec_prod (
            id_meter,
            date_measurement,
            meter_reading_kwh,
            power_kwh
        ) VALUES (
            11,
            sysdate,
            v_current_elec_prod_reading + v_random_e_prod / 12,
            v_random_e_prod
        );



    END add_reading_e_prod;


PROCEDURE add_reading_e_social IS

        v_random_e_social                       elec_social.power_kwh%TYPE := dbms_random.value(0, 2000);
        v_current_elec_social_reading           elec_social.meter_reading_kwh%TYPE;
    BEGIN
        SELECT
            meter_reading_kwh
        INTO v_current_elec_social_reading
        FROM
            elec_social
        ORDER BY
            date_measurement DESC
        FETCH FIRST 1 ROW ONLY;

        dbms_output.put_line(v_current_elec_social_reading);
        INSERT INTO elec_social (
            id_meter,
            date_measurement,
            meter_reading_kwh,
            power_kwh
        ) VALUES (
            131,
            sysdate,
            v_current_elec_social_reading + v_random_e_social/12,
            v_random_e_social
        );


    END add_reading_e_social;


END pkg_meter_reading;

我尝试使用EXCEPTION,但它没有像我想要的那样工作。 对我来说,这似乎不是一个好的解决方案。

例外 当no_data_found v_current_elec_social_reading := 0;

我不知道如何以其他方式解决它。

SQL PLSQL的

评论

0赞 tinazmu 10/30/2023
您也可以只在一个语句中使用,除非您确实必须将工作拆分为两个语句(也许您想在插入之前对第一个语句的结果执行其他操作。这样可以避免使用 FETCH 及其no_data_found错误。INSERT...SELECT with ROW_NUMBER()

答:

1赞 Littlefoot 10/30/2023 #1

你说你试图使用异常处理部分,但是 - 你为什么不发布它?你把它放在哪里?可能应该在内部块中,而不是在过程级别,因为它不会“修复”任何东西 - 插入不会发生。BEGIN-EXCEPTION-END

像这样的东西(两个过程也是如此)。

示例表:

SQL> CREATE TABLE elec_prod
  2  (
  3     id_meter            NUMBER,
  4     date_measurement    DATE,
  5     meter_reading_kwh   NUMBER,
  6     power_kwh           NUMBER
  7  );

Table created.

程序:

SQL> CREATE OR REPLACE PROCEDURE add_reading_e_prod
  2  IS
  3     v_random_e_prod              elec_prod.power_kwh%TYPE := DBMS_RANDOM.VALUE (0, 2000);
  4     v_current_elec_prod_reading  elec_prod.meter_reading_kwh%TYPE;
  5  BEGIN
  6     BEGIN                                                       --> inner block starts here
  7          SELECT meter_reading_kwh
  8            INTO v_current_elec_prod_reading
  9            FROM elec_prod
 10        ORDER BY date_measurement DESC
 11           FETCH FIRST 1 ROW ONLY;
 12     EXCEPTION
 13        WHEN NO_DATA_FOUND
 14        THEN
 15           v_current_elec_prod_reading := 0;
 16     END;                                                          --> inner block ends here
 17
 18     DBMS_OUTPUT.put_line (v_current_elec_prod_reading);
 19
 20     INSERT INTO elec_prod (id_meter,
 21                            date_measurement,
 22                            meter_reading_kwh,
 23                            power_kwh)
 24          VALUES (11,
 25                  SYSDATE,
 26                  v_current_elec_prod_reading + v_random_e_prod / 12,
 27                  v_random_e_prod);
 28  END add_reading_e_prod;
 29  /

Procedure created.

测试:首次执行:

SQL> EXEC add_reading_e_prod;

PL/SQL procedure successfully completed.

SQL> SELECT * FROM elec_prod;

  ID_METER DATE_MEASUREMENT    METER_READING_KWH  POWER_KWH
---------- ------------------- ----------------- ----------
        11 30.10.2023 07:09:37        152,728356 1832,74027
   

第二次执行:

SQL> EXEC add_reading_e_prod;

PL/SQL procedure successfully completed.

SQL> SELECT * FROM elec_prod;

  ID_METER DATE_MEASUREMENT    METER_READING_KWH  POWER_KWH
---------- ------------------- ----------------- ----------
        11 30.10.2023 07:09:37        152,728356 1832,74027
        11 30.10.2023 07:09:56        230,574188  934,14998

SQL>

因此,是的 - 内部块处理它。

评论

0赞 Pitt Bear 10/30/2023
我在 2 个地方尝试过。在手术结束时和中间。最后,它根本没有插入。当我把 EXCEPTION 放在中间时,当 exption 没有发生时,它也没有插入。
0赞 Littlefoot 10/30/2023
它应该有。您能否(通过编辑原始问题)发布有关此的更多信息 - 可能是您的SQL*Plus会话来说明它?
0赞 Littlefoot 10/30/2023
我编辑了答案并发布了整个测试用例。它表明内部块确实有帮助。如果你失败了,那可能取决于你。如果您发布了您到底做了什么,也许我们可以提供帮助。
0赞 Pitt Bear 10/30/2023
好吧,我发现了一个错误。你的代码很好。谢谢
0赞 Pitt Bear 10/31/2023
这是一个好的解决方案吗?我不确定,但我想我在某处听说过不要将逻辑放在 EXCEPTION 部分?你能给我一个另一个解决方案的想法吗?也许这可以在 CASE 中完成?