使用带参数的游标时出现问题
Issue in using cursor with parameters
我正在使用带有输入和输出参数的游标从 select 查询中获取数据并每隔一定时间插入到另一个 table 中:-
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;
/
我不太清楚 this.Could 的语法,请你帮忙解决这个问题?
我收到以下错误:-
[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>
除此之外,您不需要使用如此复杂的代码;一个简单的 insert
就可以完成这项工作。请注意我声明变量的方式——它们的数据类型可能应该是 date
,除非 b.t_date
列的数据类型是 varchar2
。如果是,那么你的问题比声明部分的顺序更大。永远不要将日期存储为字符串。
此外,您应该切换到显式连接,而不是 老式的 from
子句,其中所有表都用逗号分隔,并且连接是 mixed 有条件。你的代码有点奇怪,因为它包含 on
关键字但没有 join
和 where
所以......那是行不通的。
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 为您完成大部分 dirty 工作(打开游标,从游标中获取数据,注意何时退出循环,关闭游标):
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;
/
如果您仍想按照自己的方式进行,请这样做。你的程序的其余部分看起来没问题(无法测试,我没有你的表格)。
我正在使用带有输入和输出参数的游标从 select 查询中获取数据并每隔一定时间插入到另一个 table 中:-
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;
/
我不太清楚 this.Could 的语法,请你帮忙解决这个问题? 我收到以下错误:-
[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>
除此之外,您不需要使用如此复杂的代码;一个简单的 insert
就可以完成这项工作。请注意我声明变量的方式——它们的数据类型可能应该是 date
,除非 b.t_date
列的数据类型是 varchar2
。如果是,那么你的问题比声明部分的顺序更大。永远不要将日期存储为字符串。
此外,您应该切换到显式连接,而不是 老式的 from
子句,其中所有表都用逗号分隔,并且连接是 mixed 有条件。你的代码有点奇怪,因为它包含 on
关键字但没有 join
和 where
所以......那是行不通的。
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 为您完成大部分 dirty 工作(打开游标,从游标中获取数据,注意何时退出循环,关闭游标):
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;
/
如果您仍想按照自己的方式进行,请这样做。你的程序的其余部分看起来没问题(无法测试,我没有你的表格)。