将光标与参数一起使用时出现问题



我使用一个同时具有输入和输出参数的光标从选择查询中提取数据,并每隔一段时间插入另一个表:-

DECLARE
i_start_date varchar2(20) := '2019-01-02';
i_end_date varchar2(20):= '2019-01-09';
v_ack_records record_inst%ROWTYPE;
CURSOR record_inst(i_start_date varchar2,i_end_date varchar2) IS
select a.id,b.status
from table1.a,table2 b
on a.msg_id=b.msg_id
and b.t_date>=i_start_date 
and b.t_date<=i_end_date ;
BEGIN
OPEN record_inst; 
LOOP
FETCH record_inst INTO v_ack_records;
EXIT WHEN record_inst%NOTFOUND;
INSERT INTO test_table
(id,status)
VALUES(v_ack_records.id,
v_ack_records.status);
END LOOP;
CLOSE record_inst;
COMMIT; 
END; 
/

我不太清楚该使用什么语法。你能帮忙吗?我得到了以下错误:-

[Error Code: 6550, SQL State: 65000]  ORA-06550: line 5, column 15:
PLS-00320: the declaration of the type of this expression is incomplete or malformed
ORA-06550: line 5, column 15:
PL/SQL: Item ignored
ORA-06550: line 14, column 5:
PLS-00306: wrong number or types of arguments in call to 'RECORD_INST'
ORA-06550: line 14, column 5:
PL/SQL: SQL Statement ignored
ORA-06550: line 16, column 28:
PLS-00320: the declaration of the type of this expression is incomplete or malformed
ORA-06550: line 16, column 5:
PL/SQL: SQL Statement ignored
ORA-06550: line 22, column 15:
PL/SQL: ORA-00984: column not allowed here
ORA-06550: line 18, column 1:
PL/SQL: SQL Statement ignored

开始日期和结束日期是输入,id&状态是输出。

谢谢,

这是您编写的一个非常简化的代码;对于您的案例来说,重要的是declare部分。

SQL> declare
2    v_emp_rec    record_emp%rowtype;
3
4    cursor record_emp is
5      select empno, ename from emp;
6  begin
7    null;
8  end;
9  /
v_emp_rec    record_emp%rowtype;
*
ERROR at line 2:
ORA-06550: line 2, column 16:
PLS-00320: the declaration of the type of this expression is incomplete or
malformed
ORA-06550: line 2, column 16:
PL/SQL: Item ignored

SQL>

正如你所看到的,同样的错误。为什么?因为您首先声明了一个游标变量——它基于游标的定义——但游标还没有声明。换句话说,应该反之亦然:光标在前,变量在后:

SQL> declare
2    cursor record_emp is
3      select empno, ename from emp;
4
5    v_emp_rec    record_emp%rowtype;
6    begin
7    null;
8  end;
9  /
PL/SQL procedure successfully completed.
SQL>

除此之外,您不需要使用如此复杂的代码;简单的CCD_ 2就完成了这项工作。注意我声明变量的方式——它们的数据类型可能应该是date,除非b.t_date列的数据类型是varchar2。如果是,那么您将面临比声明部分中的顺序更大的问题。永远不要将日期存储为字符串。

此外,您应该切换到显式联接,而不是老式的from子句,其中所有表都用逗号分隔,并且联接是与条件混合的。您的代码有点奇怪,因为它包含on关键字,但没有joinwhere,所以。。。那行不通。

declare
i_start_date  date := date '2019-01-02';    -- date literal is always YYYY-MM-DD
i_end_date    date := date '2019-01-09';
begin  
insert into test_table (id, status)
select a.id, b.status
from table1 a join table2 b on a.msg_id = b.msg_id
where b.t_date between i_start_date and i_end_date;
end;
/

如果您想使用光标,请考虑光标FOR循环,因为它更容易使用;Oracle为您完成了的大部分工作(打开光标,从中提取,注意何时退出循环,关闭光标(:

declare
i_start_date  date := date '2019-01-02';
i_end_date    date := date '2019-01-09';
begin  
for cur_r in (select a.id, b.status
from table1 a join table2 b on a.msg_id = b.msg_id
where b.t_date between i_start_date and i_end_date
)
loop
insert into test_table (id, status)
values (cur_r.id, cur_r.status);
end loop;
end;
/

如果你仍然想按照你的方式进行,请这样做。你的程序的其余部分看起来还可以(无法测试,我没有你的表(。

相关内容

  • 没有找到相关文章

最新更新