Why do I get ORA-06531: reference to uninitialized collection? - oracle

I want to call a PL/SQL function with
select consult_trac.get_detail_dos_amo('12345') from dual
but I get the error:
java.sql.SQLException: ORA-06530: Reference to uninitialized composite
ORA-06512: à "CNSS_SERVICES.GET_DETAIL_DOS_AMO" at line 60 (ret(v_counter).num_doss := DS_DT.NUM_DOSS;)
My PL/SQL function is defined in a package with all the types.
Package definition:
CREATE OR REPLACE PACKAGE consult_trac AS
FUNCTION get_detail_dos_amo (p_num_doss VARCHAR2)
RETURN tab_dos_t_amo;
END consult_trac;
/
CREATE OR REPLACE PACKAGE BODY consult_trac AS
FUNCTION get_detail_dos_amo (p_num_doss VARCHAR2)
RETURN tab_dos_t_amo
IS
CURSOR DOSS_DET (num_doss VARCHAR2) IS
SELECT NUM_DOSS,
DAT_DEP,
NUM_IMMA,
NUM_IND,
P_DATE_ACTE,
CODE_EVOP,
LIB_EVOP,
CODE_DR,
LIB_DR,
C_USER,
C_GENCE,
C_NIV,
L_NIV,
DAT_SUI,
C_D_ETAT,
L_D_ETAT,
L_NAT,
NUM_RECOM,
ACCUSE,
P_MONTANT,
NUM_D_PARENT,
P_INP_DOS,
P_ICE_DOS,
P_CIN,
P_NOM,
P_PRENOM,
P_N_PAGE,
P_D_SORTIE,
P_C_CAT,
P_C_SOURCE,
C_ERROR
FROM TYP_DOSS_AMO
WHERE NUM_DOSS = p_num_doss;
CURSOR SEL_MEDIC(num_doss VARCHAR2) IS
SELECT CODE_MEDIC,
NOMBRE
FROM DOSS_MEDIC
WHERE NUM_DOSS = num_doss;
CURSOR SEL_INP(num_doss VARCHAR2) IS
SELECT CODE_INP
FROM DOSS_INP
WHERE NUM_DOSS = num_doss;
ret tab_dos_t_amo;
ret_med tab_medic;
ret_inp tab_inp;
v_counter number := 0;
v_counter_med number := 0;
v_counter_inp number := 0;
BEGIN
FOR DS_DT IN DOSS_DET(p_num_doss)
LOOP
ret(v_counter).num_doss := DS_DT.NUM_DOSS;
ret(v_counter).dat_dep := DS_DT.DAT_DEP;
ret(v_counter).num_imma := DS_DT.NUM_IMMA;
ret(v_counter).num_ind := DS_DT.NUM_IND;
ret(v_counter).p_date_acte := DS_DT.P_DATE_ACTE;
ret(v_counter).code_evop := DS_DT.CODE_EVOP;
ret(v_counter).lib_evop := DS_DT.LIB_EVOP;
ret(v_counter).code_dr := DS_DT.CODE_DR;
ret(v_counter).lib_dr := DS_DT.LIB_DR;
ret(v_counter).c_user := DS_DT.C_USER;
ret(v_counter).c_gence := DS_DT.C_GENCE;
ret(v_counter).c_niv := DS_DT.C_NIV;
ret(v_counter).l_niv := DS_DT.L_NIV;
ret(v_counter).dat_sui := DS_DT.DAT_SUI;
ret(v_counter).c_d_etat := DS_DT.C_D_ETAT;
ret(v_counter).l_d_etat := DS_DT.L_D_ETAT;
ret(v_counter).l_nat := DS_DT.L_NAT;
ret(v_counter).num_recom := DS_DT.NUM_RECOM;
ret(v_counter).accuse := DS_DT.ACCUSE;
ret(v_counter).p_montant := DS_DT.P_MONTANT;
ret(v_counter).num_d_parent := DS_DT.NUM_D_PARENT;
ret(v_counter).p_INP_dos := DS_DT.P_INP_DOS;
ret(v_counter).p_ICE_dos := DS_DT.P_ICE_DOS;
ret(v_counter).p_cin := DS_DT.P_CIN;
ret(v_counter).p_nom := DS_DT.P_NOM;
ret(v_counter).p_prenom := DS_DT.P_PRENOM;
ret(v_counter).p_n_page := DS_DT.P_N_PAGE;
ret(v_counter).p_d_sortie := DS_DT.P_D_SORTIE;
ret(v_counter).p_c_cat := DS_DT.P_C_CAT;
ret(v_counter).p_c_source := DS_DT.P_C_SOURCE;
ret(v_counter).c_error := DS_DT.C_ERROR;
FOR SM IN SEL_MEDIC(p_num_doss)
LOOP
ret_med(v_counter_med).code_medic := SM.CODE_MEDIC;
ret_med(v_counter_med).nombre := SM.NOMBRE;
v_counter_med := v_counter_med +1;
END LOOP;
FOR SI IN SEL_INP(p_num_doss)
LOOP
ret_inp(v_counter_inp).code_inp := SI.CODE_INP;
v_counter_inp := v_counter_inp +1;
END LOOP;
ret(v_counter).p_tab_medic := ret_med;
ret(v_counter).p_tab_inp := ret_inp;
v_counter := v_counter + 1;
END LOOP;
return ret;
END;
END consult_trac;
/
Types:
create or replace TYPE MEDIC AS OBJECT (
num_doss VARCHAR2(9),
code_medic VARCHAR2(10),
nombre NUMBER);
create or replace TYPE tab_medic IS TABLE OF MEDIC;
create or replace TYPE INP AS OBJECT (
num_doss VARCHAR2(9),
code_inp VARCHAR2(20));
create or replace TYPE tab_INP IS TABLE OF INP;
create or replace TYPE TYP_DOS_AMO AS OBJECT (
num_doss VARCHAR2(9),
dat_dep DATE,
num_imma VARCHAR2(13),
num_ind VARCHAR2(20),
p_date_acte DATE,
code_evop VARCHAR2(20),
lib_evop VARCHAR2(30),
code_dr VARCHAR2(20),
lib_dr VARCHAR2(30),
c_user VARCHAR2(20),
c_gence VARCHAR2(20),
c_niv VARCHAR2(20),
l_niv VARCHAR2(20),
dat_sui DATE,
c_d_etat VARCHAR2(20),
l_d_etat VARCHAR2(20),
l_nat VARCHAR2(30),
num_recom VARCHAR2(30),
accuse VARCHAR2(30),
p_montant VARCHAR2(20),
num_d_parent VARCHAR2(9),
p_INP_dos VARCHAR2(20),
p_ICE_dos VARCHAR2(20),
p_cin VARCHAR2(10),
p_nom VARCHAR2(20),
p_prenom VARCHAR2(20),
p_n_page VARCHAR2(20),
p_d_sortie DATE,
p_c_cat VARCHAR2(15),
p_c_source VARCHAR2(15),
p_tab_medic tab_medic,
p_tab_inp tab_inp,
c_error INTEGER
);
create or replace TYPE tab_INP IS TABLE OF INP;

A nested table object is not the same as an associative array, so it must be initialised before usage.
Thus
ret tab_dos_t_amo
probably needs to be
ret tab_dos_t_amo := tab_dos_t_amo();
Now as you want to add elements to it, you need to add an index to the array, for example
ret.extend;
which now allows you to reference ret(1).
You didn't show us the definition for tab_dos_t_amo but I assume it is a table of dos_t_amo. So each entry in that table is an object, which means your code:
ret(v_counter).num_doss := DS_DT.NUM_DOSS;
ret(v_counter).dat_dep := DS_DT.DAT_DEP;
ret(v_counter).num_imma := DS_DT.NUM_IMMA;
would now look like
ret.extend;
ret(v_counter) := dos_t_amo(
DS_DT.DAT_DEP,
DS_DT.NUM_IMMA,
...
...);

Related

How call a procedure with a TYPE RECORD?

I did a data insertion procedure in a package and I want to use it together with a RECORD TYPE but I don't know what to call it.
I want to at least be able to enter 'codigo' with the other values in null
CREATE TABLE TB_CRUD_MAC"
( "K_CODIGO" NUMBER(10,0),
"A_NUMNIT" VARCHAR2(11 BYTE),
"N_NOMBRE" VARCHAR2(11 BYTE),
"N_APELLI" VARCHAR2(11 BYTE),
"F_FECHA" DATE,
"I_ESTADO" VARCHAR2(1 BYTE),
"K_CLASIF" VARCHAR2(1 BYTE) )
create or replace PACKAGE PK_CRUD_MAC AS
TYPE R_REGISTRO IS RECORD (
codigo TB_CRUD_MAC.K_CODIGO%TYPE,
numnit TB_CRUD_MAC.A_NUMNIT%TYPE,
nombre TB_CRUD_MAC.N_NOMBRE%TYPE,
apelli TB_CRUD_MAC.N_APELLI%TYPE,
fecha TB_CRUD_MAC.F_FECHA%TYPE,
estado TB_CRUD_MAC.I_ESTADO%TYPE,
clasif TB_CRUD_MAC.K_CLASIF%TYPE
);
PROCEDURE PR_INSERT_REGISTRO (P_R_REGISTRO R_REGISTRO);
END;
create or replace PACKAGE BODY PK_CRUD_MAC AS
PROCEDURE PR_INSERT_REGISTRO (P_R_REGISTRO R_REGISTRO)
IS
BEGIN
INSERT INTO TB_CRUD_MAC VALUES P_R_REGISTRO;
END;
END;
Yeah, you cannot do that. You have to pass in a complete record, example:
declare
reg PK_CRUD_MAC.R_REGISTRO;
begin
reg.codigo := 6;
PK_CRUD_MAC.PR_INSERT_REGISTRO(reg);
end;
However, if all you are trying to do is insert the record with the same type as the table column definitions, you do not need to create your own pl/sql record. You can do as below:
create or replace PACKAGE PK_CRUD_MAC2 AS
PROCEDURE PR_INSERT_REGISTRO (P_R_REGISTRO TB_CRUD_MAC%ROWTYPE);
END;
create or replace PACKAGE BODY PK_CRUD_MAC2 AS
PROCEDURE PR_INSERT_REGISTRO (P_R_REGISTRO TB_CRUD_MAC%ROWTYPE)
IS
BEGIN
INSERT INTO TB_CRUD_MAC VALUES P_R_REGISTRO;
END;
END;
You CANNOT do what you are attempting, at least the way you are attempting. You have defined you procedure as taking a record structure as input variable but then calling it with a single value. That is the wrong type error you get.
You can however overload the procedure in the package.
create or replace package pk_crud_mac as
type r_registro is record (
codigo tb_crud_mac.k_codigo%type,
numnit tb_crud_mac.a_numnit%type,
nombre tb_crud_mac.n_nombre%type,
apelli tb_crud_mac.n_apelli%type,
fecha tb_crud_mac.f_fecha%type,
estado tb_crud_mac.i_estado%type,
clasif tb_crud_mac.k_clasif%type
);
procedure pr_insert_registro (p_r_registro r_registro);
procedure pr_insert_registro (codigo tb_crud_mac.k_codigo%type);
end;
create or replace package body pk_crud_mac as
procedure pr_insert_registro (p_r_registro r_registro)
is
begin
insert into tb_crud_mac values p_r_registro;
end;
procedure pr_insert_registro (p_codigo tb_crud_mac.k_codigo%type)
is
begin
insert into tb_crud_mac values (p_codigo);
end;
end;
Add a function as a constructor that will initialize your record. Define all parameters as optional. And call. For example
create table TB_CRUD_MAC(
K_CODIGO number(10)
,A_NUMNIT varchar2(11)
,N_NOMBRE varchar2(11)
,N_APELLI varchar2(11)
,F_FECHA date
,I_ESTADO varchar2(1)
,K_CLASIF varchar2(1)
);
create or replace package PK_CRUD_MAC
is
subtype R_REGISTRO is TB_CRUD_MAC%rowtype;
function New (pK_CODIGO TB_CRUD_MAC.K_CODIGO%type := null
,pA_NUMNIT TB_CRUD_MAC.A_NUMNIT%type := null
,pN_NOMBRE TB_CRUD_MAC.N_NOMBRE%type := null
,pN_APELLI TB_CRUD_MAC.N_APELLI%type := null
,pF_FECHA TB_CRUD_MAC.F_FECHA%type := null
,pI_ESTADO TB_CRUD_MAC.I_ESTADO%type := null
,pK_CLASIF TB_CRUD_MAC.K_CLASIF%type := null) return R_REGISTRO;
procedure PR_INSERT_REGISTRO (P_R_REGISTRO R_REGISTRO);
end;
/
create or replace package body PK_CRUD_MAC
is
function New (pK_CODIGO TB_CRUD_MAC.K_CODIGO%type := null
,pA_NUMNIT TB_CRUD_MAC.A_NUMNIT%type := null
,pN_NOMBRE TB_CRUD_MAC.N_NOMBRE%type := null
,pN_APELLI TB_CRUD_MAC.N_APELLI%type := null
,pF_FECHA TB_CRUD_MAC.F_FECHA%type := null
,pI_ESTADO TB_CRUD_MAC.I_ESTADO%type := null
,pK_CLASIF TB_CRUD_MAC.K_CLASIF%type := null) return R_REGISTRO
is
vR_REGISTRO R_REGISTRO;
begin
vR_REGISTRO.K_CODIGO := pK_CODIGO;
vR_REGISTRO.A_NUMNIT := pA_NUMNIT;
vR_REGISTRO.N_NOMBRE := pN_NOMBRE;
vR_REGISTRO.N_APELLI := pN_APELLI;
vR_REGISTRO.F_FECHA := pF_FECHA ;
vR_REGISTRO.I_ESTADO := pI_ESTADO;
vR_REGISTRO.K_CLASIF := pK_CLASIF;
return vR_REGISTRO;
end;
procedure PR_INSERT_REGISTRO (P_R_REGISTRO R_REGISTRO)
is
begin
insert into TB_CRUD_MAC values P_R_REGISTRO;
end;
end;
/
begin
PK_CRUD_MAC.PR_INSERT_REGISTRO(PK_CRUD_MAC.New(pK_CODIGO => :K_CODIGO));
-- commit;
end;
/

How to fix 'identifier 'ACCOUNT_REQUEST_TBL' must be declared

an error
FRM-40735: WHEN-BUTTON-PRESSED trigger raised unhandled
exception ORA-06502
raises when I try to insert my fields as below. What could be the reason ?
DECLARE
v_reqid NUMBER(10) := :txtreqid;
v_branch VARCHAR2(15) := :txtbranch;
v_acctype VARCHAR2(15) := :txtacctype;
v_title VARCHAR2(4) := :txttitle;
v_firstname VARCHAR2(15) := :register.txtfirstname;
v_lastname VARCHAR2(15) := :register.TXLASTNAME;
v_DOB DATE := :txtdob;
v_workp NUMBER(10) := :txtworkp;
v_hphone NUMBER(10) := :txthphone;
v_address VARCHAR2(30) := :txtadd;
v_state_info VARCHAR2(15) := :txtstate;
v_hphone NUMBER(10) := :txtzip;
v_email VARCHAR2(30) := :txtemail;
v_status VARCHAR2(10) := :txtstatus;
v_user_name VARCHAR2(30) := :txtun;
v_password VARCHAR2(30) := :txtpw;
BEGIN
INSERT INTO account_request_tbl
VALUES(v_reqid,v_branch,v_acctype,v_title,v_firstname, v_lastname,v_DOB,v_workp,
v_hphone,v_address,v_state_info,v_hphone,v_email,v_status,v_user_name,v_password);
COMMIT;
message('You have succesfully created a new account!');
END;
Assuming the variable name are derived from the table account_request_tbl columns' names, define your variables' data types by using account_request_tbl.<column_name>%type instead. Since your issue is related with the mismatch of data types and/or precision between local variables and data types of columns :
DECLARE
v_reqid account_request_tbl.reqid%type := :txtreqid;
v_branch account_request_tbl.branch%type := :txtbranch;
v_acctype account_request_tbl.acctype%type := :txtacctype;
v_title account_request_tbl.title%type := :txttitle;
v_firstname account_request_tbl.firstname%type := :register.txtfirstname;
v_lastname account_request_tbl.lastname%type := :register.TXLASTNAME;
v_DOB account_request_tbl.dob%type := :txtdob;
v_workp account_request_tbl.workp%type := :txtworkp;
v_hphone account_request_tbl.hphone%type := :txthphone;
v_address account_request_tbl.address%type := :txtadd;
v_state_info account_request_tbl.state_info%type := :txtstate;
v_email account_request_tbl.email%type := :txtemail;
v_status account_request_tbl.status%type := :txtstatus;
v_user_name account_request_tbl.user_name%type := :txtun;
v_password account_request_tbl.password%type := :txtpw;
BEGIN
INSERT INTO account_request_tbl(reqid,branch,acctype,title,firstname,lastname,dob,workp,
hphone, address, state_info, email, status, user_name, password )
VALUES(v_reqid,v_branch,v_acctype,v_title,v_firstname, v_lastname,v_DOB,v_workp,
v_hphone,v_address,v_state_info,v_email,v_status,v_user_name,
v_password);
IF SQL%ROWCOUNT > 0 THEN
COMMIT;
message('You have succesfully created a new account!');
ELSE
ROLLBACK;
message('Unfortunately, you couldn''t create a new account !!!');
END IF;
END;
The reson for the error might vary such as the field :txtadd's length doesn't fit for VARCHAR2(30), or the value in :txtreqid field is of string type .. etc.
Indeed no need to declare variables explicitly, direct substitution within the INSERT statement is enough( thanks #AndyDan ) as
INSERT INTO account_request_tbl(reqid,branch,acctype,title,firstname,lastname,dob,workp,
hphone, address, state_info, email, status, user_name, password )
VALUES(:txtreqid,:txtbranch,:txtacctype,:txttitle,:register.txtfirstname,
:register.txlastname, :txtdob, :txtworkp,:txthphone, :txtadd, :txtstate,:txtemail,
:txtstatus, :txtun, :txtpw);

In PL/SQL can I set a variable dynamically?

In Oracle 12c R2, I have a function which receives a row type as a variable. In the function I want to read a table which contains a column name and a value, I want to then populate the row type variable passed in using the column name and the data from the table I read.
Here is a simplistic idea of what I want to do;
CREATE TABLE table_to_be_updated
(
key_value number,
cola varchar2(2),
colb varchar2(2),
colc varchar2(2),
cold varchar2(2),
cole varchar2(2),
colf varchar2(2)
);
CREATE TABLE table_default_value
(
default_stuff number,
column_name varchar(30),
column_default_value varchar2(2)
);
function do_defaults(in_table table_to_be_updated%rowtype, in_value number) return table_to_be_updated%rowtype
is
out_table table_to_be_updated%rowtype := in_table;
cursor my_curs
is
select * from table_default_value where default_stuff = in_value;
begin
for default_rec in my_curs
loop
out_table.[default_rec.column_name] := default_rec.column_default_value
end loop;
return out_table;
end;
insert into table_default_value (default_stuff,column_name,column_default_value) values (1,'cola','xx'));
insert into table_default_value (default_stuff,column_name,column_default_value) values (1,'colc','aa'));
insert into table_default_value (default_stuff,column_name,column_default_value) values (1,'cole','bb'));
In the line;
out_table.[default_rec.column_name] := [default_rec.column_default_value]
[default_rec.column_name] would be the column name, from the cursor, in out_table name I want to move data to.
and
[default_rec.column_default_value] is the value from the cursor I want to move into that column.
I suspect that what I want to do is impossible in PL/SQL, but I thought I'd ask.
There are other ways to accomplish updating the table directly, specifically using dynamic SQL with execute immediate, but I have a number of similar tables which all need to have the same things done to them, and I would prefer a single function to work on a record and then pass it back to have the calling routine update the proper table.
Here is the best I can come up with;
function do_defaults(in_table table_to_be_updated%rowtype, in_value number) return table_to_be_updated%rowtype
is
TYPE DEFAULT_TYPE IS TABLE OF VARCHAR2(2)
INDEX BY VARCHAR2(30);
DEFAULT_ARRAY DEFAULT_TYPE;
out_table table_to_be_updated%rowtype := in_table;
cursor my_curs
is
select * from table_default_value where default_stuff = in_value;
begin
DEFAULT_ARRAY('cola') := null;
DEFAULT_ARRAY('colb') := null;
DEFAULT_ARRAY('colc') := null;
DEFAULT_ARRAY('cold') := null;
DEFAULT_ARRAY('cole') := null;
DEFAULT_ARRAY('colf') := null;
for default_rec in my_curs
loop
DEFAULT_ARRAY(default_rec.column_name) := default_rec.column_default_value
end loop;
out_table.cola := DEFAULT_ARRAY('cola');
out_table.colb := DEFAULT_ARRAY('colb');
out_table.colc := DEFAULT_ARRAY('colc');
out_table.cold := DEFAULT_ARRAY('cold');
out_table.cole := DEFAULT_ARRAY('cole');
out_table.colf := DEFAULT_ARRAY('colf');
return out_table;
end;

Fetching data dynamically in Collections

I need to use collections as below, but want to print the output dynamically instead of specifying PL01, PL02, PL03...as this is going to be bigger list. If not possible using RECORD type, how can this be achieved using collections.
Business scenario : Having a item price list in an excel sheet as price list code in the first row (each column refers to a price list) and different items in each row. The number of price list and the items will differ every time. Now i need to populate this excel in collections in same format (Table with items in rows and price list code as columns) and use it to update the correct price list.
DECLARE
TYPE RT IS RECORD (ITEM VARCHAR2(20),
PL01 NUMBER,
PL02 NUMBER,
PL03 NUMBER,
PL04 NUMBER,
PL05 NUMBER);
TYPE TT IS TABLE OF RT;
MY_REC RT;
MY_TAB TT := TT();
BEGIN
MY_TAB.EXTEND;
MY_TAB(1).ITEM := 'ABC';
MY_TAB(1).PL01 := '40';
MY_TAB(1).PL02 := '42';
MY_TAB(1).PL03 := '44';
MY_TAB(1).PL04 := '46';
MY_TAB(1).PL05 := '48';
MY_TAB.EXTEND;
MY_TAB(2).ITEM := 'DEF';
MY_TAB(2).PL01 := '60';
MY_TAB(2).PL02 := '62';
MY_TAB(2).PL03 := '64';
MY_TAB(2).PL04 := '66';
MY_TAB(2).PL05 := '68';
FOR I IN 1..2
LOOP
Dbms_Output.PUT_LINE(MY_TAB(I).ITEM||' - '||MY_TAB(I).PL01||' - '||MY_TAB(I).PL02||' - '||
MY_TAB(I).PL03||' - '||MY_TAB(I).PL04||' - '||MY_TAB(I).PL05);
END LOOP;
END;
/
One way is to create TYPE as objects and using a TABLE function to display by passing a REFCURSOR.
CREATE OR REPLACE TYPE RT AS OBJECT ( ITEM VARCHAR2(20),
PL01 NUMBER,
PL02 NUMBER,
PL03 NUMBER,
PL04 NUMBER,
PL05 NUMBER
);
/
CREATE OR REPLACE TYPE TT AS TABLE OF RT;
/
VARIABLE x REFCURSOR;
DECLARE
MY_TAB TT := TT();
BEGIN
MY_TAB.EXTEND(2); --allocate 2 elements
MY_TAB(1) := RT ( 'ABC',40,42,44,46,48);--you can assign all once/index
MY_TAB(2) := RT ( 'DEF',60,62,64,66,68);
OPEN :x FOR SELECT * FROM TABLE(MY_TAB);
END;
/
PRINT x
ITEM PL01 PL02 PL03 PL04 PL05
-------------------- ---------- ---------- ---------- ---------- ----------
ABC 40 42 44 46 48
DEF 60 62 64 66 68
You can use a PL/SQL table inside the RECORD. Try this:
DECLARE
TYPE PL_TABLE_TYPE IS TABLE OF NUMBER;
TYPE RT IS RECORD (ITEM VARCHAR2(20), PL_TABLE PL_TABLE_TYPE);
TYPE TT IS TABLE OF RT;
MY_TAB TT := TT();
BEGIN
MY_TAB.EXTEND;
MY_TAB(MY_TAB.LAST).ITEM := 'ABC';
MY_TAB(MY_TAB.LAST).PL_TABLE := PL_TABLE_TYPE(40,42,33,46,48);
--> Why do you assign strings like '40' if you have a NUMBER data type?
MY_TAB.EXTEND;
MY_TAB(MY_TAB.LAST).ITEM := 'DEF';
MY_TAB(MY_TAB.LAST).PL_TABLE := PL_TABLE_TYPE(60,62,64,66,68);
FOR r IN MY_TAB.FIRST..MY_TAB.LAST LOOP
DBMS_OUTPUT.PUT(MY_TAB(r).ITEM || ' ');
FOR i IN MY_TAB(r).PL_TABLE.FIRST..MY_TAB(r).PL_TABLE.LAST LOOP
DBMS_OUTPUT.PUT(MY_TAB(r).PL_TABLE(i) || ' ');
END LOOP;
DBMS_OUTPUT.NEW_LINE;
END LOOP;
END;

ORA-12703: this character set conversion is not supported

I am encountering an Conversion error message when running the below code:
Declare
v_t MyType;
assignment_param NVARCHAR2(10);
project_name_param NVARCHAR2(100);
document_nick_name_param NVARCHAR2(100);
doc_created_by NVARCHAR2(100);
id NVARCHAR2(10);
project_launch_date NVARCHAR2(100);
assignment_type_param NVARCHAR2(100);
temp NVARCHAR2(30000);
Begin
assignment_param := get_assignment_type(f_id);
project_name_param := get_project_name(f_id);
document_nick_name_param := get_document_nick_name(f_id);
doc_created_by := get_doc_created_by(f_id);
id := get_id(f_id);
project_launch_date := get_project_launch_date(f_id);
IF (assignment_param = 'manual') THEN
assignment_type_param := 'manually';
ELSE
assignment_type_param := 'automatically';
END IF;
v_t := MyType();
v_t.EXTEND(7);
v_t(1) := 'assignment_param='||assignment_param;
v_t(2) := 'project_name_param='||project_name_param;
v_t(3) := 'document_nick_name_param='||document_nick_name_param;
v_t(4) := 'doc_created_by='||doc_created_by;
v_t(5) := 'id='||id;
v_t(6) := 'project_launch_date='||project_launch_date;
v_t(7) := 'assignment_type_param='||assignment_type_param;
temp := Replace_Email_Body_Contents(12,v_t);
End;
Also my other function has code:
CREATE OR REPLACE FUNCTION Replace_Email_Body_Contents
(
id_inparam IN NUMBER,
replace_var_loop IN MyType
)
RETURN NVARCHAR2
AS
db_string NVARCHAR2(10000);
str_1 NVARCHAR2(100);
str_2 NVARCHAR2(100);
BEGIN
--loading the email template from html string column of form_templates_data table;
SELECT HTML_STRING INTO db_string FROM TABLE WHERE ID = id_inparam;
FOR i IN 1..replace_var_loop.COUNT LOOP
SELECT SUBSTR(replace_var_loop(i), 0, INSTR(replace_var_loop(i), '=')-1) INTO str_1 FROM DUAL;
SELECT SUBSTR(replace_var_loop(i), INSTR(replace_var_loop(i), '=')+1) INTO str_2 FROM DUAL;
db_string := REPLACE(db_string , str_1 , str_2 );
END LOOP;
dbms_output.put_line(db_string);
RETURN db_string;
END;
/
Error:
ORA-12703: this character set conversion is not supported
ORA-06512: at "REPLACE_EMAIL_BODY_CONTENTS", line 13
ORA-06512: at line 32
HTML_STRING is a column in the table referred in above code and the values corresponding to f_id looks like:
Notification
Hello,
You have been assignment_param-assigned a document.
Project Name: project_name_param
Document Nickname: document_nick_name_param
Doc Created By: doc_created_by
LCA ID: lca_id
Project Launch Date: project_launch_date
Based on the evaluation of the checklist, an Engineer has been assignment_type_param assigned to work with the project team.

Resources