I have a procedure which receive as input parameter a record with 170 columns (it is based on the structure of a table).
In the procedure I want to call a debugging procedure one of whose parameters is a text string containing all the field names and values of this record.
For example:
CREATE OR REPLACE PROCEDURE xxx (pi_record IN table_name%ROWTYPE) as
text VARCHAR2(10000) := NULL;
BEGIN
...
text := 'pi_record.column1 = ' || pi_record.column1 || CHR(13) ||
'pi_record.column2 = ' || pi_record.column2 || CHR(13) ||
...
'pi_record.column170 = ' || pi_record.column170;
logging_procedure (text);
...
END;
Is there any simple way to achieve this in a dynamic way (looping through record fields names and values) without enumerating all of them?
Maybe something like this:
CREATE OR REPLACE PROCEDURE xxx (pi_record IN table_name%ROWTYPE) as
text VARCHAR2(10000) := NULL;
BEGIN
...
LOOP in pi_record.columns
text := text || CHR(13) || pi_record.column.name || ' : ' || pi_record.column.value
END LOOP
logging_procedure (text);
...
END;
Many thanks,
Here's one way to do that. A package spec contains a variable whose type matches the one we'll use in a procedure.
SQL> set serveroutput on
SQL> create or replace package pkg_xxx
2 as
3 dept_rec dept%rowtype;
4 end;
5 /
Package created.
SQL> create or replace procedure xxx (pi_record in dept%rowtype)
2 as
3 text varchar2 (10000) := null;
4 l_str varchar2 (200);
5 l_var varchar2 (200);
6 begin
7 pkg_xxx.dept_rec := pi_record;
8
9 for cur_r in ( select column_name
10 from user_tab_columns
11 where table_name = 'DEPT'
12 order by column_id)
13 loop
14 l_str :=
15 'begin '
16 || ':x := to_char(pkg_xxx.dept_rec.'
17 || cur_r.column_name
18 || '); '
19 || 'end; ';
20
21 execute immediate l_str using out l_var;
22
23 text := text || chr (10) || cur_r.column_name || ' = ' || l_var;
24 end loop;
25
26 dbms_output.put_line (text);
27 end;
28 /
Procedure created.
Now, let's pass something to the procedure and see what happens:
SQL> declare
2 cursor c1
3 is
4 select *
5 from dept
6 where deptno = 10;
7
8 c1r c1%rowtype;
9 begin
10 open c1;
11 fetch c1 into c1r;
12 close c1;
13
14 xxx (c1r);
15 end;
16 /
DEPTNO = 10
DNAME = ACCOUNTING
LOC = NEW YORK
PL/SQL procedure successfully completed.
SQL>
Huh, kind of works (if that's what you asked). Of course, it is just an example, you'll have to modify it if you want to get something really smart (hint: DATE columns).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With