plsql - Cursor for loop using a selection instead of a table ( oracle ) -
i'm writing procedure fill child table parent table. child table has more fields parent table ( should ). i've conjured cursor wich point selection, wich join of multiple tables. here's code got far :
create or replace procedure pop_occ_lezione x lezione%rowtype; cursor cc y as( select codice_corso, nome_modulo, data_inizio_ed_modulo diem, giorno_lezione, ora_inizio_lezione o_i, ora_fine_lezione o_f, anno, id_cdl, nome_sede, locazione_modulo loc lezione join ( select id_cdl, anno, codice_corso corso ) using (codice_corso) join ( select codice_corso, locazione_modulo modulo ) using (codice_corso) join ( select nome_sede, id_cdl cdl ) using (id_cdl) case when extract (month data_inizio_ed_modulo) < 9 extract (year data_inizio_ed_modulo) - 1 else extract (year data_inizio_ed_modulo) end = extract (year sysdate+365) ) select * y sem_check(y.diem,sysdate+365) = 1; -- begin fetch cc x; exit when cc%notfound; insert occr_lezione values ( x.codice_corso, x.nome_modulo, x.diem,x.giorno_lezione, x.ora_inizio_lezione, to_date(to_char(next_day(sysdate,x.giorno_lezione),'dd-mm-yyyy') || to_char(x.ora_inizio_lezione,' hh24:mi'),'dd-mm-yyyy hh24:mi'), to_date(to_char(next_day(sysdate,x.giorno_lezione),'dd-mm-yyyy') || to_char(x.ora_fine_lezione,' hh24:mi'),'dd-mm-yyyy hh24:mi'), x.nome_sede, 0, x.loc ); end loop; end; /
but of course won't work, because variable x has type of initial table row, wich has less columns selection. unfortunally far know rowtype variable needed cycle trough cursor, in order fetch data it. can see contraddiction ? how can change code ? there type of variable wich can crafted reflect row query result ? or maybe way cycle trough data in cursor without using support variable ? or maybe entirely different ? please let me know.
ok suggested tried :
insert occr_lezione( codice_corso, nome_modulo, data_inizio_ed_modulo, giorno_lezione, ora_inizio_lezione, ora_fine_lezione, anno, id_cdl, nome_sede, locazione_modulo ) y as( select codice_corso, nome_modulo, data_inizio_ed_modulo, giorno_lezione, ora_inizio_lezione, ora_fine_lezione, anno, id_cdl, nome_sede, locazione_modulo lezione join ( select id_cdl, anno, codice_corso corso ) using (codice_corso) join ( select codice_corso, locazione_modulo modulo ) using (codice_corso) join ( select nome_sede, id_cdl cdl ) using (id_cdl) case when extract (month data_inizio_ed_modulo) < 9 extract (year data_inizio_ed_modulo) - 1 else extract (year data_inizio_ed_modulo) end = extract (year sysdate+365) ) select * y sem_check(y.data_inizio_ed_modulo,sysdate+365) = 1; end; /
but says pl/sql: ora-00904: "locazione_modulo": invalid identifier
wich isn't true, because query return table in wich such column present... missing ? code compiled no errors, occurs when try fire te procedure. in table occr_lezione can see :
create table occr_lezione ( codice_corso varchar2(20) not null, nome_modulo varchar2(50) not null, data_inizio_ed_modulo date not null, giorno_lezione number(1) not null, ora_inizio_lezione date not null, data_inizio_occr_lezione date, data_fine_occr_lezione date not null, nome_sede varchar2(30) not null, num_aula varchar2(3) not null, tipo_aula varchar2(20) not null, -- constraint fk_occr_lezione_lezione foreign key (codice_corso,nome_modulo,data_inizio_ed_modulo,giorno_lezione,ora_inizio_lezione) references lezione(codice_corso,nome_modulo,data_inizio_ed_modulo,giorno_lezione,ora_inizio_lezione) on delete cascade, constraint fk_occr_lezione_aula foreign key (nome_sede,num_aula,tipo_aula) references aula(nome_sede,num_aula,tipo_aula) on delete set null, constraint pk_occr_lezione primary key (codice_corso,nome_modulo,data_inizio_ed_modulo,giorno_lezione,ora_inizio_lezione,data_inizio_occr_lezione), check ( trunc(data_inizio_occr_lezione) = trunc(data_fine_occr_lezione) ), -- data inizio = data fine // prenotazione giornaliera check ( data_inizio_occr_lezione < data_fine_occr_lezione ) -- ora inizio < ora fine // coerenza temporale
there not column named locazione_modulo, last column tipo_aula same type , size of locazione modulo :
create table modulo ( codice_corso varchar2(20) not null, nome_modulo varchar2(50), locazione_modulo varchar2(20) not null, -- constraint fk_modulo_corso foreign key(codice_corso) references corso(codice_corso) on delete cascade, constraint pk_modulo primary key(codice_corso,nome_modulo), check (locazione_modulo in ('aula','laboratorio','conferenze')) );
so should irrelevant, right ?
if want use explicit cursors, can declare x
of type cc%rowtype
create or replace procedure pop_occ_lezione cursor cc ... x cc%rowtype; ...
unless using explicit cursors because want able explicitly fetch data local collections can leverage later on in procedure, code using implicit cursors tends preferrable. eliminates need fetch
, close
cursor or write exit
condition , implicitly bulk fetch minimize context shifts.
begin x in cc loop insert occr_lezione ... end loop; end;
of course, in either case, hope you'd choose more meaningful names local variables-- x
, cc
don't tell variables doing.
if doing taking data 1 set of tables , inserting table, more efficient write single insert
statement rather coding pl/sql loop.
insert occr_lezione( <<column list>> ) select <<column list>> <<tables joining in cursor definition>> <<conditions cursor definition>>
Comments
Post a Comment