oracle - 在 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(???);
解决方案
既然您知道如何在没有参数的情况下执行过程,我还想指出您的过程存在的问题。
不需要为循环游标定义记录变量。
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' )