pl/sql updateXML must be declared - plsql

I am trying to insert into an xmltype something, I read the oracle docs and it says I should use updateXML or insertChildXML, but the compler says, updateXML must be declared
searched everywhere but i cant find any reference to missing functions
I am using the 11g, as a must, this is the start of a very long assignment and i can't do much without the functions to modify xmltype
Help, how do I solve that compiler error?
CREATE OR REPLACE PROCEDURE comentar_evento
(
id_usuario IN NUMBER,
id_lugar IN NUMBER,
nombre_evento IN VARCHAR2,
comentario IN VARCHAR2
)
IS
otag VARCHAR2(50);
ctag VARCHAR2(50);
xmlPath VARCHAR2(50);
xpEnd VARCHAR2(50);
ag XMLType;
BEGIN
otag := '<comentario>';
ctag := '</comentario>';
xmlPath := '/agenda/evento/[nombre_evento="';
xpEnd := '"]/comentarios';
xmlPath := xmlPath || nombre_evento || xpEnd;
SELECT agenda INTO ag FROM usuario WHERE id = id_usuario;
insertChildXML(ag, xmlPath, 'comentario', otag || comentario || ctag);
END;
/
http://docs.oracle.com/cd/B28359_01/appdev.111/b28369/xdb04cre.htm#ADXDB0400

see the documentation again.
Doc reads as "INSERTCHILDXML SQL Function".
CREATE OR REPLACE PROCEDURE comentar_evento
(
id_usuario IN NUMBER,
id_lugar IN NUMBER,
nombre_evento IN VARCHAR2,
comentario IN VARCHAR2
)
IS
otag VARCHAR2(50);
ctag VARCHAR2(50);
xmlPath VARCHAR2(50);
xpEnd VARCHAR2(50);
ag XMLType;
v_result xmltype;
BEGIN
otag := '<comentario>';
ctag := '</comentario>';
xmlPath := '/agenda/evento/[nombre_evento="';
xpEnd := '"]/comentarios';
xmlPath := xmlPath || nombre_evento || xpEnd;
SELECT agenda INTO ag FROM usuario WHERE id = id_usuario;
v_result := insertChildXML(ag, xmlPath, 'comentario', otag || comentario || ctag);
END;
/

Related

Why do I get ORA-06531: reference to uninitialized collection while trying to call procedure?

i am trying to call the procedure my_package.procedure_test like bellow:
declare
v_counter BINARY_INTEGER := 1;
a tbl_familles;
v_mytable tbl_familles;
begin
PK_SOA_Famille_Test.get_famille('zz','zz', v_mytable);
while v_counter <= v_mytable.count
loop
Dbms_Output.Put_Line(v_mytable(v_counter).nom);
v_counter := v_counter + 1;
end loop;
end;
But i get the exception:
ORA-06531: reference to uninitialized collection
The Package definition:
CREATE OR REPLACE Package PK_SOA_Famille_Test as
PROCEDURE get_famille
(num_ass IN VARCHAR2, num_indd IN VARCHAR2,
OutTableParam OUT tbl_familles);
end PK_SOA_Famille_Test;
The Procedure body:
CREATE OR REPLACE PACKAGE BODY PK_SOA_Famille_Test AS
PROCEDURE get_famille
(num_ass IN VARCHAR2, num_indd IN VARCHAR2, OutTableParam OUT tbl_familles) IS
v_counter number := 0;
Cursor C_typ_famille
(
num_ass varchar2 ,num_indd varchar2
) Is
SELECT nom, prenom, num_imm ,num_ind ,nat_int ,dat_naiss, num_cin, der_stat, der_sit, datsit, indpere, indmere
from typ_famille
where (num_imm = num_ass AND num_ind = num_indd) ;
C2 C_typ_famille%ROWTYPE;
BEGIN
IF num_indd is null then
for EmpCursor in
(select nom,prenom,num_imm ,num_ind, nat_int, dat_naiss, num_cin, der_stat, der_sit, datsit, indpere, indmere
from typ_famille
where num_imm = num_ass)
loop
v_counter := v_counter + 1;
OutTableParam(v_counter).nom := EmpCursor.nom;
OutTableParam(v_counter).prenom := EmpCursor.prenom;
OutTableParam(v_counter).num_imm := EmpCursor.num_imm;
OutTableParam(v_counter).num_ind := EmpCursor.num_ind;
OutTableParam(v_counter).nat_int := EmpCursor.nat_int ;
OutTableParam(v_counter).dat_naiss := EmpCursor.dat_naiss;
OutTableParam(v_counter).num_cin := EmpCursor.num_cin;
OutTableParam(v_counter).der_stat := EmpCursor.der_stat;
OutTableParam(v_counter).der_sit := EmpCursor.der_sit;
OutTableParam(v_counter).datsit := EmpCursor.datsit;
OutTableParam(v_counter).indpere := EmpCursor.indpere;
OutTableParam(v_counter).indmere := EmpCursor.indmere;
end loop;
END IF ;
END get_famille;
END PK_SOA_Famille_Test;
/
I have also created the types rec_famille as an object and tbl_familles as a table of rec_famille in schema level.
When num_indd is NOT NULL then PK_SOA_Famille_Test.get_famille effectively does nothing. This leaves OutTableParam uninitialized. You could have an ELSE in your IF-statement with OutTableParam := tbl_familles(); as EJ Egyed suggested.
Additionally, looping through a cursor to fill a collection is a waste: you should use BULK COLLECT instead.
CREATE OR REPLACE PACKAGE BODY pk_soa_famille_test IS
PROCEDURE get_famille(num_ass IN VARCHAR2,
num_indd IN VARCHAR2,
outtableparam OUT) IS
BEGIN
IF num_indd IS NULL THEN
SELECT nom,
prenom,
num_imm,
num_ind,
nat_int,
dat_naiss,
num_cin,
der_stat,
der_sit,
datsit,
indpere,
indmere
BULK COLLECT
INTO outtableparam
FROM typ_famille
WHERE num_imm = num_ass;
ELSE
outtableparam := tbl_familles;
END IF;
END get_famille;
END pk_soa_famille_test;

create a procedure with cursor as parameter

I wrote this code and it works ok:
declare
cursor c_emp is
select last_name, first_name from employees;
type c_list is table of employees.last_name%type index by binary_integer;
type c_list2 is table of employees.first_name%type index by binary_integer;
last_list c_list;
first_list c_list2;
counter integer := 0;
begin
for i in c_emp loop
counter := counter + 1;
last_list(counter) := i.last_name;
first_list(counter) := i.first_name;
dbms_output.put_line('Employee(' || counter || '): ' || last_list(counter) || ' ' || first_list(counter));
end loop;
end;
/
This time I am trying to make procedure with parameters that I can insert the table name and column into the cursor. And I have tried with this :
create or replace procedure show_data(tab_name in varchar2, data_list in varchar2)
is
str varchar2(100);
str2 varchar2(100);
column_name varchar2(100);
begin
str := 'select ' || data_list || ' from ' || tab_name;
for vRec in str loop
dbms_output.put_line(str);
end loop;
end;
/
It gave a error which the str is not a cursor. I am not sure that if cursor can be done in this way, but from the error it seems it can't.
Which part of my code is wrong, or because I didn't declare my cursor? But if i declare my cursor, I can't get the parameter by using dynamic sql way.
The below should produce the same result as your original PL/SQL block. Note that the table_name can be dynamic and so can the data_list but you need to know the column names in the data_list to be able to fetch from the cursor and then print them.
create or replace procedure show_data(tab_name in varchar2
, data_list in varchar2)
is
str varchar2(100);
str2 varchar2(100);
column_name varchar2(100);
TYPE cursor_ref IS REF CURSOR;
vRec_cursor cursor_ref;
counter integer = 0;
last_name employee.last_name%TYPE;
first_name employee.first_name%TYPE;
begin
str := 'select ' || data_list || ' from ' || tab_name;
open vRec_cursor for str;
loop
FETCH vRec_cursor INTO last_name, first_name;
EXIT WHEN vRec_cursor%NOTFOUND;
dbms_output.put_line('Employee(' || counter || '): ' || last_name || ' ' || first_name;
counter = counter + 1;
end loop;
end;
/
NOTE: Haven't run the above code yet

i have a function which returns multiple o/p i need to call this function to insert in a table

create or replace type branch_warehouse as object (wh_id number,wh_name varchar2(100));
create or replace type id_warehouse_list as table of branch_warehouse;
function get_ware_house_branch(p_BRANCH_IDS in out varchar2)
return id_warehouse_list is
l_warehouse_list id_warehouse_list := id_warehouse_list();
str varchar2(300);
begin
str := 'SELECT BRANCH_WAREHOUSE(w.wh_id, w.wh_name)
FROM POD_WAREHOUSE_MASTER W
where ( W.BRANCH_ID IN (' || p_BRANCH_IDS || '))';
execute immediate str bulk collect into l_warehouse_list;
for i in l_warehouse_list.first..l_warehouse_list.last loop
dbms_output.put_line(l_warehouse_list(i).wh_id || ', ' || l_warehouse_list(i).wh_name);
end loop;
return l_warehouse_list;
end;
procedure insert_place_warehouse_map(p_PLACE_NAME in varchar2,
p_BRANCH_IDS in number,
p_status out varchar2,
p_status_dtl out varchar2) is
v_ID number;
l_warehouse_list id_warehouse_list := id_warehouse_list();
begin
v_ID := get_place_id (p_PLACE_NAME);
l_warehouse_list := get_ware_house_branch(p_BRANCH_IDS);
for i in l_warehouse_list.first..l_warehouse_list.last loop
insert into pod_place_warehouse_map(
id,
place_id,
wh_id,
wh_name)
values(
pod_unique_val_seq.nextval,
v_ID,
l_warehouse_list(i).wh_id,
l_warehouse_list(i).wh_name);
v_rec_cnt := sql%rowcount;
end loop;
commit;
p_status := 'SUCESS';
p_status_dtl := v_rec_cnt||' Record Inserted Successfully';
exception
when others then
rollback;
p_status_dtl := sqlcode||' - '||substr(sqlerrm,1,100);
p_status := 'ERROR';
end;
i am getting error p_BRANCH_IDS cannot be used as assignment operator in the 2nd code
first code is working,
please help
This is because the parameter is declared as in out in first code, but as in in second.

SYS.DBMS_DDL.WRAP not allowing pragma and intctx

I am using the below procedure to wrap the PL/SQL Code.
declare
l_source DBMS_SQL.VARCHAR2A;
l_wrap DBMS_SQL.VARCHAR2A;
l_wrap1 clob;
typ_ibt utl_file.file_type;
cnt number := 0;
v_directory varchar2(400) := 'd:\ftpedi\eqpm\eqpm_hold\';
cursor cur_name_get is
select distinct name object_name,type object_type
from user_source
where type = 'PROCEDURE'
and name = 'PROCESS_TIME_INSERT';
cursor cut_text_get ( p_type in varchar2 , p_name in varchar2 ) is
select replace(text,chr(10),'') text
from user_source
where type = p_type
and name = p_name;
begin
for i in cur_name_get
loop
l_source.delete;l_wrap.delete;
open cut_text_get ( i.object_type,i.object_name );
fetch cut_text_get bulk collect into l_source;
close cut_text_get;
l_source (1) := 'CREATE OR REPLACE ' || l_source (1);
l_wrap := SYS.DBMS_DDL.WRAP(ddl => l_source,
lb => 1,
ub => l_source.count);
for i in 1..l_wrap.count
loop
if i = 1
then
l_wrap1 := l_wrap(i);
else
l_wrap1 := l_wrap1 || l_wrap(i);
end if;
insert into ibt_global_inter_transfer ( git_process_id,git_c_1)
values ( 3004, l_wrap1 );
end loop;
end loop;
exception when others
then
dbms_output.put_line('sqlerrm '||sqlerrm||dbms_utility.format_error_backtrace);
end;
The above procedures warps the normal procedure, but not allowing the special character like 'PRAGMA'.
The below is the sample procedure, which is not wrapping.
CREATE OR REPLACE
PROCEDURE xml_insert ( p_in_xml in xmltype ,p_status out varchar2,p_message out varchar2) is
intctx DBMS_XMLSTORE.ctxtype;
rows number;
begin
p_status := 'S';
p_message := 'Success';
intctx := Dbms_xmlstore.newcontext('IBT_GLOBAL_INTER_TRANSFER');
dbms_xmlstore.clearupdatecolumnlist(intctx);
dbms_xmlstore.setupdatecolumn(intCtx,'GIT_PROCESS_ID');
dbms_xmlstore.setupdatecolumn(intCtx,'GIT_SESSION_ID');
rows := Dbms_xmlstore.insertxml(intctx,p_in_xml);
dbms_xmlstore.closecontext(intctx);
exception when others
then
p_status := 'R';
p_message := sqlerrm||dbms_utility.format_error_backtrace;
return;
end;
Could anyone help?
Update
(I misunderstood the problem. I thought you meant the wrapped code wasn't created, now I understand the real problem is that the wrapped output does not compile.)
Remove the replace, there needs to be white space between some of the lines.
Replace:
--select replace(text,chr(10),'') text
with:
select text
Procedure:
CREATE OR REPLACE
PROCEDURE xml_insert ( p_in_xml in xmltype ,p_status out varchar2,p_message out varchar2) is
intctx DBMS_XMLSTORE.ctxtype;
rows number;
pragma autonomous_transaction; --ADDED
begin
p_status := 'S';
p_message := 'Success';
intctx := Dbms_xmlstore.newcontext('IBT_GLOBAL_INTER_TRANSFER');
dbms_xmlstore.clearupdatecolumnlist(intctx);
dbms_xmlstore.setupdatecolumn(intCtx,'GIT_PROCESS_ID');
dbms_xmlstore.setupdatecolumn(intCtx,'GIT_SESSION_ID');
rows := Dbms_xmlstore.insertxml(intctx,p_in_xml);
dbms_xmlstore.closecontext(intctx);
exception when others
then
p_status := 'R';
p_message := sqlerrm||dbms_utility.format_error_backtrace;
return;
end;
/
PL/SQL Block wrapping code:
declare
l_source DBMS_SQL.VARCHAR2A;
l_wrap DBMS_SQL.VARCHAR2A;
l_wrap1 clob;
typ_ibt utl_file.file_type;
cnt number := 0;
v_directory varchar2(400) := 'd:\ftpedi\eqpm\eqpm_hold\';
cursor cur_name_get is
select distinct name object_name,type object_type
from user_source
where type = 'PROCEDURE'
and name = 'XML_INSERT'; --CHANGED
cursor cut_text_get ( p_type in varchar2 , p_name in varchar2 ) is
--select replace(text,chr(10),'') text --WOOPS!
select text
from user_source
where type = p_type
and name = p_name;
begin
for i in cur_name_get
loop
l_source.delete;l_wrap.delete;
open cut_text_get ( i.object_type,i.object_name );
fetch cut_text_get bulk collect into l_source;
close cut_text_get;
l_source (1) := 'CREATE OR REPLACE ' || l_source (1);
l_wrap := SYS.DBMS_DDL.WRAP(ddl => l_source,
lb => 1,
ub => l_source.count);
for i in 1..l_wrap.count
loop
if i = 1
then
l_wrap1 := l_wrap(i);
else
l_wrap1 := l_wrap1 || l_wrap(i);
end if;
--insert into ibt_global_inter_transfer ( git_process_id,git_c_1)
--values ( 3004, l_wrap1 );
dbms_output.put_line(l_wrap1);
end loop;
end loop;
exception when others
then
dbms_output.put_line('sqlerrm '||sqlerrm||dbms_utility.format_error_backtrace);
end;
/

Get Installation Sequence of Oracle Objects

Ok, I have a complex recursion problem. I want to get a dependecy installation sequence of all of my objcts (all_objects table) in my Oracle 11g database.
First I have created a view holding all dependencies
create or replace
view REALLY_ALL_DEPENDENCIES as
select *
from ALL_DEPENDENCIES
union
select owner, index_name, 'INDEX', table_owner, table_name, table_type, null, null
from all_indexes
union
select p.owner, p.table_name, 'TABLE', f.owner, f.table_name, 'TABLE', null, null
from all_constraints p
join all_constraints f
on F.R_CONSTRAINT_NAME = P.CONSTRAINT_NAME
and F.CONSTRAINT_TYPE = 'R'
and p.constraint_type='P'
;
/
EDIT
I have tried do concate all dependencies by using this function:
create
or replace
function dependency(
i_name varchar2
,i_type varchar2
,i_owner varchar2
,i_level number := 0
,i_token clob := ' ') return clob
is
l_token clob := i_token;
l_exist number := 0;
begin
select count(*) into l_exist
from all_objects
where object_name = i_name
and object_type = i_type
and owner = i_owner;
if l_exist > 0 then
l_token := l_token || ';' || i_level || ';' ||
i_name || ':' || i_type || ':' || i_owner;
else
-- if not exist function recursion is finished
return l_token;
end if;
for tupl in (
select distinct
referenced_name
,referenced_type
,referenced_owner
from REALLY_ALL_DEPENDENCIES
where name = i_name
and type = i_type
and owner = i_owner
)
loop
-- if cyclic dependency stop and shout!
if i_token like '%' || tupl.referenced_name || ':' || tupl.referenced_type || ':' || tupl.referenced_owner || '%' then
select count(*) into l_exist
from REALLY_ALL_DEPENDENCIES
where name = tupl.referenced_name
and type = tupl.referenced_type
and owner = tupl.referenced_owner;
if l_exist > 0 then
return '!!!CYCLIC!!! (' || i_level || ';' || tupl.referenced_name || ':' || tupl.referenced_type || ':' || tupl.referenced_owner || '):' || l_token;
end if;
end if;
-- go into recursion
l_token := dependency(
tupl.referenced_name
,tupl.referenced_type
,i_owner /* I just want my own sources */
,i_level +1
,l_token);
end loop;
-- no cyclic condition and loop is finished
return l_token;
end;
/
And I can query through
select
object_name
,object_type
,owner
,to_char(dependency(object_name, object_type, owner)) as dependecy
from all_objects
where owner = 'SYSTEM'
;
Ok, maybe it is something like "cheating" but you can not do cyclic dependencies at creation time. So at least as a human beeing I am only able to create one object after another :-) And this sequence should be "reverse engineer able".
Now I am more interested in a solution than before ;-) And it is still about the tricky part ... "How can I select all soures from a schema orderd by its installation sequence (dependent objects list prior the using object)"?
It is just some kind of sorting problem, insn't it?
Usually you "cheat" by creating the objects in a particular order. For example, you might make sequences first (they have zero dependencies). Then you might do tables. After that, package specs, then package bodies, and so on.
Keep in mind that it is possible to have cyclic dependencies between packages, so there are cases where it will be impossible to satisfy all dependencies at creation anyway.
What's the business case here? Is there a real "problem" or just an exercise?
EDIT
The export tool we use exports objects in the following order:
Database Links
Sequences
Types
Tables
Views
Primary Keys
Indexes
Foreign Keys
Constraints
Triggers
Materialized Views
Materialized View Logs
Package Specs
Package Bodies
Procedures
Functions
At the end, we run the dbms_utility.compile_schema procedure to make sure everything is valid and no dependencies are missed. If you use other object types than these, I'm not sure where they'd go in this sequence.
Ok, I had some time to look at the job again and I want to share the results. Maybe anotherone comes across this thread searching for a solution. First of all I did the SQLs as SYS but I think you can do it in every schema using public synonyms.
The Procedure "exec obj_install_seq.make_install('SCOTT');" makes a clob containing a sql+ compatible sql file, assuming your sources are called "object_name.object_type.sql". Just spool it out.
Cheers
Chris
create global temporary table DEPENDENCIES on commit delete rows as
select * from ALL_DEPENDENCIES where 1=2 ;
/
create global temporary table install_seq(
idx number
,seq number
,iter number
,owner varchar2(30)
,name varchar2(30)
,type varchar2(30)
) on commit delete rows;
/
create global temporary table loop_chk(
iter number
,lvl number
,owner varchar2(30)
,name varchar2(30)
,type varchar2(30)
) on commit delete rows;
/
create or replace package obj_install_seq is
procedure make_install(i_schema varchar2 := 'SYSTEM');
end;
/
create or replace package body obj_install_seq is
subtype install_seq_t is install_seq%rowtype;
type dependency_list_t is table of DEPENDENCIES%rowtype;
procedure set_list_data(i_schema varchar2 := user)
is
l_owner varchar2(30) := i_schema;
begin
-- collect all dependencies
insert into DEPENDENCIES
select *
from (select *
from ALL_DEPENDENCIES
where owner = l_owner
and referenced_owner = l_owner
union
select owner, index_name, 'INDEX', table_owner, table_name, table_type, null, null
from all_indexes
where owner = l_owner
and table_owner = l_owner
union
select p.owner, p.table_name, 'TABLE', f.owner, f.table_name, 'TABLE', null, null
from all_constraints p
join all_constraints f
on F.R_CONSTRAINT_NAME = P.CONSTRAINT_NAME
and F.CONSTRAINT_TYPE = 'R'
and p.constraint_type='P'
and p.owner = f.owner
where p.owner = l_owner
) all_dep_tab;
-- collect all objects
insert into install_seq
select rownum, null,null, owner, object_name, object_type
from (select distinct owner, object_name, object_type, created
from all_objects
where owner = l_owner
order by created) objs;
end;
function is_referencing(
i_owner varchar2
,i_name varchar2
,i_type varchar2
,i_iter number
,i_level number := 0
) return boolean
is
l_cnt number;
begin
select count(*) into l_cnt
from loop_chk
where name = i_name
and owner = i_owner
and type = i_type
and iter = i_iter
and lvl < i_level;
insert into loop_chk values(i_iter,i_level,i_owner,i_name,i_type);
if l_cnt > 0 then
return true;
else
return false;
end if;
end;
procedure set_seq(
i_owner varchar2
,i_name varchar2
,i_type varchar2
,i_iter number
,i_level number := 0)
is
-- l_dep all_dependencies%rowtype;
l_idx number;
l_level number := i_level +1;
l_dep_list dependency_list_t;
l_cnt number;
begin
-- check for dependend source
begin
select * bulk collect into l_dep_list
from dependencies
where name = i_name
and owner = i_owner
and type = i_type;
if l_dep_list.count <= 0 then
-- recursion finished
return;
end if;
end;
for i in 1..l_dep_list.count loop
if is_referencing(
l_dep_list(i).referenced_owner
,l_dep_list(i).referenced_name
,l_dep_list(i).referenced_type
,i_iter
,i_level
) then
-- cyclic dependecy
update install_seq
set seq = 999
,iter = i_iter
where name = l_dep_list(i).referenced_name
and owner = l_dep_list(i).referenced_owner
and type = l_dep_list(i).referenced_type;
else
--chek if sequence is earlier
select count(*) into l_cnt
from install_seq
where name = l_dep_list(i).referenced_name
and owner = l_dep_list(i).referenced_owner
and type = l_dep_list(i).referenced_type
and seq > l_level *-1;
-- set sequence
if l_cnt > 0 then
update install_seq
set seq = l_level *-1
,iter = i_iter
where name = l_dep_list(i).referenced_name
and owner = l_dep_list(i).referenced_owner
and type = l_dep_list(i).referenced_type;
end if;
-- go recusrion
set_seq(
l_dep_list(i).referenced_owner
,l_dep_list(i).referenced_name
,l_dep_list(i).referenced_type
,i_iter + (i-1)
,l_level
);
end if;
end loop;
end;
function get_next_idx return number
is
l_idx number;
begin
select min(idx) into l_idx
from install_seq
where seq is null;
return l_idx;
end;
procedure make_install(i_schema varchar2 := 'SYSTEM')
is
l_obj install_seq_t;
l_idx number;
l_iter number := 0;
l_install_clob clob := chr(10);
begin
set_list_data(i_schema);
l_idx := get_next_idx;
while l_idx is not null loop
l_iter := l_iter +1;
select * into l_obj from install_seq where idx = l_idx;
update install_seq set iter = l_iter where idx = l_idx;
update install_seq set seq = 0 where idx = l_idx;
set_seq(l_obj.owner,l_obj.name,l_obj.type,l_iter);
l_idx := get_next_idx;
end loop;
for tupl in ( select * from install_seq order by seq, iter, idx ) loop
l_install_clob := l_install_clob || '#' ||
replace(tupl.name,' ' ,'') || '.' ||
replace(tupl.type,' ' ,'') || '.sql' ||
chr(10);
end loop;
l_install_clob := l_install_clob ||
'exec dbms_utility.compile_schema(''' || upper(i_schema) || ''');';
-- do with the install file what you want
DBMS_OUTPUT.PUT_LINE(dbms_lob.substr(l_install_clob,4000));
end;
end;
/

Resources