Это очень упрощенный код, который вы написали; Для вашего случая важен раздел 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
. Если это так, то у вас есть большая проблема, чем порядок в разделе объявлений. Никогда не храните даты в виде строк.
Кроме того, вы должны переключиться на явные объединения вместо oldfashioned from
, где все таблицы разделены запятыми и где объединения смешаны с условиями. Ваш код несколько странный, поскольку он содержит ключевое слово 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
l oop, так как он намного проще в использовании; Oracle выполняет большую часть работы dirty за вас (открытие курсора, выборка из него, внимание при выходе из l oop, закрытие курсора):
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;
/
Если вы все еще хотите сделать это по-своему, пожалуйста, сделайте это. Остальная часть вашей процедуры выглядит нормально (не могу проверить, у меня нет ваших таблиц).