首页 > 解决方案 > 在 Oracle 中执行过程

问题描述

我正在尝试编写一个将已付款发票从paid_invoices表中插入到invoice_archive表中的过程。只有那些早于或等于 2014 年 5 月 31 日的已付发票应被转移。

这是我的程序:

SQL> create or replace procedure paid_invoice_transfer as
  cursor paid is
    select *
      from paid_invoices
     where invoice_total = credit_total + payment_total
       and payment_date <= '2014-05-31';
  invoice_archive_text paid%rowtype;
begin
  for invoice_archive_text in paid loop
    dbms_output.put_line(invoice_archive_text.invoice_id);
    insert into invoice_archive values invoice_archive_text;
  end loop;
end;
/

我不确定此时要执行什么:

SQL> set serveroutput on;
SQL> execute paid_invoice_transfer(???);

标签: oraclestored-proceduresplsql

解决方案


既然您知道如何在没有参数的情况下执行过程,我还想指出您的过程存在的问题。

不需要为循环游标定义记录变量。

invoice_archive_text paid%rowtype

当您在 for 循环中使用它时,PL/SQL 会自动创建它。我会更进一步,请您避免循环运行INSERT。只需使用简单INSERT INTO target_table select * from source_table并明确指定列名即可安全。

如果要显示通过 插入的 id DBMS_OUTPUT.PUT_LINE,请将其存储在一个集合中并单独循环以用于显示目的(仅当您认为需要显示时)。

我还想向您展示如何传递执行的日期参数,因此我将传递 payment_date。在您的过程中,您错误地将其与文字字符串而不是日期进行比较。NLS_DATE_如果参数与字符串不匹配,它必然会失败。

CREATE OR REPLACE PROCEDURE paid_invoice_transfer ( p_payment_date DATE ) AS
     TYPE tab_inv IS TABLE OF  paid_invoices.invoice_id%type;
     t_tab tab_inv; 
BEGIN


 SELECT invoice_id BULK COLLECT INTO t_tab
          FROM paid_invoices
                  WHERE invoice_total = credit_total + payment_total 
               AND payment_date <= p_payment_date;

    FOR i IN t_tab.FIRST..t_tab.LAST LOOP
          dbms_output.put_line(t_tab(i));
     END LOOP;

INSERT INTO invoice_archive ( column1,column2,column3) select col1,col2,col3
      FROM paid_invoices
     WHERE invoice_total = credit_total + payment_total
       AND payment_date <= p_payment_date; 

END;
/

set serveroutput on
execute paid_invoice_transfer(DATE '2014-05-31' )

推荐阅读