ORA-12703: this character set conversion is not supported - oracle

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.

Related

FireDac Call Function in Oracle

My code :
FDStoredProc1.StoredProcName := 'aaaaa' ;
with FDStoredProc1.Params do begin
Clear;
with Add do begin
ParamType := ptInput;
DataType := ftInteger;
end;
end;
FDStoredProc1.Params[0].Value := StrToint(edit1.Text) ;
edit1.Text := FDStoredProc1.ExecFunc() ;
My code in Oracle :
create or replace FUNCTION AAAAA (pn number) RETURN VARCHAR2 AS
BEGIN
update dmnv set thuong = pn ;
commit ;
RETURN '3'
END AAAAA;
There is no error when running, but the parameter is NULL at Oracle Server (version 12). So function is exec on Server with wrong parameter (the true parameter is the value in edit1.text).I have typed a number at edit1.
Give the parameter a name.
with Add do begin
Name := 'pn';
ParamType := ptInput;
DataType := ftInteger;
end;
with FDQuery1.SQL do begin
Clear;
Add('begin');
Add(' select aaaaa(8) from dual ;');
Add('end;');
end;
FDQuery1.ExecSQL;
Also get error.a INTO clause is expected

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;

expressions is of wrong type PIPELINED FUNCTION

Good afternoon everybody.
I have the following problem, I am loading a query to the cursor "c_Pol_Vig_Ant" and after certain validations I save the results in a list
TYPE r_Pol_Vig_Ant IS RECORD(
NUMPOL USRAXVM00.Vm_Poliza.NUMPOL%TYPE,
IDEOBSER USRAXVM00.Vm_Obser_Poliza.IDEOBSER%TYPE,
NUMAVISO USRAXVM00.Vm_Obser_Poliza.NUMAVISO%TYPE,
FECINIVIG USRAXVM00.Vm_Poliza.FECINIVIG%TYPE,
FECFINVIG USRAXVM00.Vm_Poliza.FECFINVIG%TYPE,
FECVCT USRAXVM00.VM_GIROS_FINANCIAMIENTO.FECVCT%TYPE,
ORDEN USRAXVM00.VM_GIROS_FINANCIAMIENTO.NUMGIRO%TYPE,
IDGIRO USRAXVM00.VM_GIROS_FINANCIAMIENTO.IDGIRO%TYPE,
CODMONEDA USRAXVM00.VM_ACREENCIA.CODMONEDA%TYPE,
MTOACREMONEDA USRAXVM00.VM_ACREENCIA.MTOACREMONEDA%TYPE,
STSGIRO USRAXVM00.VM_GIROS_FINANCIAMIENTO.STSGIRO%TYPE,
CODPROD USRAXVM00.Vm_Poliza.CODPROD%TYPE,
PENDIENTE USRAXVM00.VM_ACREENCIA.MTOACREMONEDA%TYPE,
TOTAL USRAXVM00.VM_ACREENCIA.MTOACREMONEDA%TYPE,
COBRADO USRAXVM00.VM_ACREENCIA.MTOACREMONEDA%TYPE,
FECHAEMISAVISO USRAXVM00.Vm_Obser_Poliza.FECHA%TYPE,
CODCANAL USRAXVM00.Vm_Poliza.CODCANAL%TYPE,
CANAL USRAXVM00.Vm_Tercero.NOMTER%TYPE,
CODINTER USRAXVM00.Vm_Part_Inter_Pol.CODINTER%TYPE,
AGENTE USRAXVM00.Vm_Tercero.NOMTER%TYPE,
CODPLAN USRAXVM00.Vm_Cond_Financiamiento.CODPLAN%TYPE,
NOMPLAN USRAXVM00.VM_PLAN_FINANCIAMIENTO.NOMPLAN%TYPE,
ORIGEN VARCHAR2(4),
VIGENCIA VARCHAR2(20)
);
TYPE tab_Pol_Vig_Ant IS TABLE OF r_Pol_Vig_Ant;
TYPE tab_Lista IS TABLE OF r_Pol_Vig_Ant INDEX BY BINARY_INTEGER;
FOR x IN c_Pol_Vig_Ant LOOP
IF x.STSGIRO = 'CAS' OR x.STSGIRO = 'AND' THEN
v_Valor := USRAXVM00.PO_POL_REN_VIG_ANT.Depurar_And_Cas(x.NUMAVISO, x.IDGIRO, x.ORDEN);
IF v_Valor <> 1 THEN
v_Cont := v_Cont + 1;
p_Datos(v_Cont).NUMPOL := x.NUMPOL;
p_Datos(v_Cont).IDEOBSER := x.IDEOBSER;
p_Datos(v_Cont).NUMAVISO := x.NUMAVISO;
p_Datos(v_Cont).FECINIVIG := x.FECINIVIG;
p_Datos(v_Cont).FECFINVIG := x.FECFINVIG;
p_Datos(v_Cont).FECVCT := x.FECVCT;
p_Datos(v_Cont).ORDEN := x.ORDEN;
p_Datos(v_Cont).IDGIRO := x.IDGIRO;
p_Datos(v_Cont).CODMONEDA := x.CODMONEDA;
p_Datos(v_Cont).MTOACREMONEDA := x.MTOACREMONEDA;
p_Datos(v_Cont).STSGIRO := x.STSGIRO;
p_Datos(v_Cont).CODPROD := x.CODPROD;
p_Datos(v_Cont).PENDIENTE := x.PENDIENTE;
p_Datos(v_Cont).TOTAL := x.TOTAL;
p_Datos(v_Cont).COBRADO := x.COBRADO;
p_Datos(v_Cont).FECHAEMISAVISO := x.FECHAEMISAVISO;
p_Datos(v_Cont).CODCANAL := x.CODCANAL;
p_Datos(v_Cont).CANAL := x.CANAL;
p_Datos(v_Cont).CODINTER := x.CODINTER;
p_Datos(v_Cont).AGENTE := x.AGENTE;
p_Datos(v_Cont).CODPLAN := x.CODPLAN;
p_Datos(v_Cont).NOMPLAN := x.NOMPLAN;
p_Datos(v_Cont).ORIGEN := x.ORIGEN;
p_Datos(v_Cont).VIGENCIA := x.VIGENCIA;
END IF;
END IF;
END LOOP;
The error is the following, when making the query to a PIPELINE function sending as parameter my list I get the error expressions is of wrong type.
FOR x IN p_Datos.First..p_Datos.Last LOOP
SELECT COUNT(DISTINCT t.VIGENCIA)
INTO v_NroVigencias
FROM table(USRAXVM00.PO_POL_REN_VIG_ANT.F_Obtener_Datos(p_Listar => p_Datos)) t
WHERE t.NUMPOL = p_Datos(x).NUMPOL;
IF v_NroVigencias = 1 THEN
p_Datos.DELETE(x);
END IF;
END LOOP;
This is my function:
FUNCTION F_Obtener_Datos(p_Listar IN tab_Lista) RETURN tab_Pol_Vig_Ant PIPELINED IS
p_ListaDatos r_Pol_Vig_Ant;
BEGIN
IF p_Listar.Count > 0 THEN
FOR x IN p_Listar.First..p_Listar.Last LOOP
p_ListaDatos.NUMPOL := p_Listar(x).NUMPOL;
p_ListaDatos.NUMAVISO := p_Listar(x).NUMAVISO;
p_ListaDatos.FECINIVIG := p_Listar(x).FECINIVIG;
p_ListaDatos.FECFINVIG := p_Listar(x).FECFINVIG;
p_ListaDatos.FECVCT := p_Listar(x).FECVCT;
p_ListaDatos.ORDEN := p_Listar(x).ORDEN;
p_ListaDatos.IDGIRO := p_Listar(x).IDGIRO;
p_ListaDatos.CODMONEDA := p_Listar(x).CODMONEDA;
p_ListaDatos.MTOACREMONEDA := p_Listar(x).MTOACREMONEDA;
p_ListaDatos.STSGIRO := p_Listar(x).STSGIRO;
p_ListaDatos.CODPROD := p_Listar(x).CODPROD;
p_ListaDatos.PENDIENTE := p_Listar(x).PENDIENTE;
p_ListaDatos.TOTAL := p_Listar(x).TOTAL;
p_ListaDatos.COBRADO := p_Listar(x).COBRADO;
p_ListaDatos.FECHAEMISAVISO := p_Listar(x).FECHAEMISAVISO;
p_ListaDatos.CANAL := p_Listar(x).CANAL;
p_ListaDatos.CODINTER := p_Listar(x).CODINTER;
p_ListaDatos.AGENTE := p_Listar(x).AGENTE;
p_ListaDatos.CODPLAN := p_Listar(x).CODPLAN;
p_ListaDatos.NOMPLAN := p_Listar(x).NOMPLAN;
p_ListaDatos.ORIGEN := p_Listar(x).ORIGEN;
p_ListaDatos.VIGENCIA := p_Listar(x).VIGENCIA;
PIPE ROW(p_ListaDatos);
END LOOP;
END IF;
RETURN;
END F_Obtener_Datos;
Error: PLS-00382: expression is of wrong type
Line: 203
Text: FROM table(USRAXVM00.PO_POL_REN_VIG_ANT.F_Obtener_Datos(p_Listar => p_Datos)) t
Error: PLS-00306: wrong number or types of arguments in call to 'F_OBTENER_DATOS'
Line: 203
Text: FROM table(USRAXVM00.PO_POL_REN_VIG_ANT.F_Obtener_Datos(p_Listar => p_Datos)) t
Error: PL/SQL: ORA-00904: "USRAXVM00"."PO_POL_REN_VIG_ANT"."F_OBTENER_DATOS": invalid identifier
Line: 203
Text: FROM table(USRAXVM00.PO_POL_REN_VIG_ANT.F_Obtener_Datos(p_Listar => p_Datos)) t
Error: PL/SQL: SQL Statement ignored
Line: 201
Text: SELECT COUNT(DISTINCT t.VIGENCIA)
Thank you very much with everyone, I hope you can help me.

How to get the values of an OBJECT or ROWTYPE dynamically (Reflection) in Oracle PL/SQL?

I am trying to take a ROWTYPE, RECORD, or OBJECT type and dynamically convert it to a single string representation.
I want to do this dynamically.
Update: Doing this for an OBJECT type now working thanks to Justin Cave's feedback.
Example Data:
ID | VAL
---------
1 | BOB
Desired Output:
ID=1, VAL=BOB
Error Received:
ORA-06550: line 7, column 25:
PLS-00306: wrong number or types of arguments in call to 'TO_STRING'
ORA-06550: line 7, column 4:
PL/SQL: Statement ignored
What I have so Far (Doesn't loop through columns yet.):
CREATE OR REPLACE FUNCTION to_string (
ip_anydata in out anydata --note the "out" - this is required for the "piecewise"
)
RETURN VARCHAR2
IS
lv_typecode PLS_INTEGER;
lv_anytype anytype;
BEGIN
DBMS_OUTPUT.PUT_LINE('[Expected='||dbms_types.typecode_object||', Actual='||ip_anydata.getType(lv_anytype)||']');
--Get the typecode, and the ANYTYPE
lv_typecode := ip_anydata.getType(lv_anytype);
--Check that it's really an object
IF lv_typecode = dbms_types.typecode_object
THEN
--If it is an object, find the first item
DECLARE
lv_first_attribute_typecode pls_integer;
lv_aname varchar2(32767);
lv_result pls_integer;
lv_varchar varchar2(32767);
--Variables we don't really care about, but need for function output
lv_prec pls_integer;
lv_scale pls_integer;
lv_len pls_integer;
lv_csid pls_integer;
lv_csfrm pls_integer;
lv_attr_elt_type anytype;
BEGIN
lv_first_attribute_typecode := lv_anytype.getAttrElemInfo(
pos => 1, --First attribute
prec => lv_prec,
scale => lv_scale,
len => lv_len,
csid => lv_csid,
csfrm => lv_csfrm,
attr_elt_type => lv_attr_elt_type,
aname => lv_aname
);
--Check typecode of attribute
IF lv_first_attribute_typecode = dbms_types.typecode_varchar2
THEN
--Now that we've verified the type, get the actual value.
ip_anydata.piecewise;
lv_result := ip_anydata.getVarchar2(c => lv_varchar);
--DEBUG: Print the attribute name, in case you're curious
--dbms_output.put_line('lv_aname: '||lv_aname);
RETURN lv_aname||'='||lv_varchar;
ELSE
raise_application_error(-20000, 'Unexpected 1st Attribute Typecode: '||lv_first_attribute_typecode);
END IF;
END;
ELSE
raise_application_error(-20000, 'Unexpected Typecode: '||lv_typecode);
END IF;
END;
/
Scenario#1 - Select INTO w/ ROWTYPE:
DECLARE
lv_cv dual%ROWTYPE;
lv_str VARCHAR2(32767);
BEGIN
DBMS_OUTPUT.PUT_LINE('-----------------------------');
SELECT * INTO lv_cv FROM dual WHERE ROWNUM <= 1;
DBMS_OUTPUT.PUT_LINE(to_string(lv_cv));
END;
/
Scenario#2 - FETCH INTO w/ Cursor ROWTYPE:
DECLARE
CURSOR cv_cur IS SELECT * FROM dual WHERE ROWNUM <= 1;
lv_cv cv_cur%ROWTYPE;
lv_str VARCHAR2(32767);
BEGIN
DBMS_OUTPUT.PUT_LINE('-----------------------------');
OPEN cv_cur;
FETCH cv_cur INTO lv_cv;
CLOSE cv_cur;
DBMS_OUTPUT.PUT_LINE(to_string(lv_cv));
END;
/
Scenario#3 - Regular OBJECT: (Updated)
DECLARE
lv_cv T_CODE_VAL_REC := T_CODE_VAL_REC('BOB', 5);
lv_str VARCHAR2(32767);
lv_any ANYDATA;
BEGIN
DBMS_OUTPUT.PUT_LINE('-----------------------------');
lv_any := sys.anydata.ConvertObject(lv_cv);
DBMS_OUTPUT.PUT_LINE(to_string(lv_any));
EXCEPTION WHEN OTHERS THEN
pts2_test_valitation_util.fail(999, CHR(10)||CHR(10)||'Unexpected Error:'||CHR(10)||SQLERRM||CHR(10)||DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
END;
/

PL/SQL: Procedure not working correctly in a package

I'm working on a package with some procedures in them and I'm running into a bit of trouble. When I try to test the procedure to convert gallons to liters or the other procedures, it just prints out what was declared in the unnamed block instead of converting the numbers. Any ideas?
CREATE OR REPLACE PACKAGE eng_metric
IS
PROCEDURE convert(degree_fahrenheit IN OUT NUMBER,degree_celsius IN OUT NUMBER,measure IN VARCHAR2);
PROCEDURE convert(liters IN OUT NUMBER,gallons IN OUT NUMBER);
END eng_metric;
/
CREATE OR REPLACE PACKAGE BODY eng_metric
AS
PROCEDURE Convert
(degree_fahrenheit IN OUT NUMBER,
degree_celsius IN OUT NUMBER,
measure IN VARCHAR2)
IS
df NUMBER;
dc NUMBER;
convertf NUMBER;
measurecf VARCHAR2(4);
BEGIN
measurecf := measure;
df := degree_fahrenheit;
dc := degree_celsius;
IF measure = 'TEMP' THEN
IF dc = NULL THEN
convertf := ((df - 32) * .56);
degree_fahrenheit := convertf;
dbms_output.Put_line('The temperature in fahrenheit is '
||To_char(degree_fahrenheit));
ELSIF df = NULL THEN
convertf := (dc + 17.98) * 1.8;
degree_celsius := convertf;
END IF;
ELSE
dbms_output.Put_line('Invalid measure');
END IF;
END convert;
PROCEDURE Convert
(liters IN OUT NUMBER,
gallons IN OUT NUMBER)
IS
lit NUMBER;
gal NUMBER;
convertlg NUMBER;
BEGIN
lit := liters;
gal := gallons;
IF gal = NULL THEN
convertlg := (lit / 3.785);
liters := convertlg;
ELSIF lit = NULL THEN
convertlg := (gal * 3.785);
gallons := convertlg;
END IF;
END convert;
END eng_metric;
/
DECLARE
liters NUMBER := 25;
gallons NUMBER := 41;
nully NUMBER := NULL;
BEGIN
eng_metric.Convert(nully,gallons);
dbms_output.Put_line(To_char(gallons));
END;
/
Instead of
IF gal = NULL THEN
you need
IF gal IS NULL
What you have to remember is that NULL means "no value". It NEVER equals or fails to equal anything, including NULL. So you need to use IS NULL or IS NOT NULL, or use the NVL function to change the null to something that has a value.

Resources