Exception block in PLSQL exiting the block - oracle

I am using the following code block to update my front end segment.
But when i am compiling this
DECLARE
p_person_id NUMBER := NULL;
p_business_group_id NUMBER;
p_id_flex_num NUMBER;
------------------
p_analysis_criteria_id NUMBER := NULL;
p_person_analysis_id NUMBER := NULL;
p_per_object_version_number NUMBER := NULL;
v_err VARCHAR2 (1000) := NULL;
p_medical_id VARCHAR2 (100) := NULL;
BEGIN
FOR i IN (SELECT *
FROM xx_hr_upload_master_data_new
WHERE person_id IS NOT NULL
AND business_group_id IS NOT NULL
AND medical_id IS NOT NULL)
LOOP
p_id_flex_num := 50530;
BEGIN
SELECT sv.segment1, NVL (sit.object_version_number, 1),
sit.analysis_criteria_id, MAX (sit.person_analysis_id)
INTO p_medical_id, p_per_object_version_number,
p_analysis_criteria_id, p_person_analysis_id
FROM fnd_id_flex_structures_tl sttl,
fnd_id_flex_structures st,
per_person_analyses sit,
per_analysis_criteria sv
WHERE sttl.id_flex_structure_name = 'ISPs Medical Data'
AND sttl.LANGUAGE = USERENV ('LANG')
AND st.id_flex_code = sttl.id_flex_code
AND st.id_flex_num = sttl.id_flex_num
AND st.id_flex_num = sit.id_flex_num
AND st.id_flex_num = sv.id_flex_num
AND sit.analysis_criteria_id = sv.analysis_criteria_id
AND sit.person_id = i.person_id
--and sv.SEGMENT1 = '4602001140'
GROUP BY sv.segment1,
NVL (sit.object_version_number, 1),
sit.analysis_criteria_id;
EXCEPTION
WHEN OTHERS
THEN
p_medical_id := NULL;
p_per_object_version_number := 1;
p_person_analysis_id := NULL;
p_analysis_criteria_id := NULL;
p_person_analysis_id := NULL;
p_per_object_version_number := NULL;
p_person_id := NULL;
END;
BEGIN
------------------------------------------------
IF (p_medical_id IS NULL AND p_analysis_criteria_id IS NULL)
THEN
-- create a new record in the SIT (Special Information Type)table .
p_person_id := i.person_id;
p_medical_id := TO_CHAR (i.medical_id);
-----------------------------
hr_sit_api.create_sit
(p_validate => FALSE,
p_person_id => p_person_id,
p_business_group_id => i.business_group_id,
p_id_flex_num => p_id_flex_num,
p_effective_date => TRUNC (SYSDATE),
p_date_from => TRUNC (SYSDATE),
p_segment1 => p_medical_id,
p_analysis_criteria_id => p_analysis_criteria_id,
p_person_analysis_id => p_person_analysis_id,
p_pea_object_version_number => p_per_object_version_number
);
ELSE
-- employee has previous Billing_Acc_Num then update that number in the SIT table .
hr_sit_api.update_sit
(p_validate => FALSE,
p_person_analysis_id => p_person_analysis_id,
p_pea_object_version_number => p_per_object_version_number,
p_date_from => TRUNC (SYSDATE),
p_segment1 => p_medical_id,
p_analysis_criteria_id => p_analysis_criteria_id
);
END IF;
UPDATE xx_hr_upload_master_data_new xx
SET xx.error_msg = 'Done',
xx.emp_data = 'Done'
WHERE xx.business_group_id = i.business_group_id
AND xx.employee_number = i.employee_number;
EXCEPTION
WHEN OTHERS
THEN
p_analysis_criteria_id := NULL;
p_person_analysis_id := NULL;
p_per_object_version_number := NULL;
p_person_id := NULL;
p_medical_id := NULL;
v_err := NULL;
v_err := SQLERRM;
UPDATE xx_hr_upload_master_data_new xx
SET xx.error_msg = v_err
WHERE xx.business_group_id = i.business_group_id
AND xx.employee_number = i.employee_number;
END;
END LOOP;
COMMIT;
END;
Now when the select query is not fetching anything, the exception block is entered where all the variables are initiated to null.
I want that after this the begin where the create api is called inside the condition IF (p_medical_id IS NULL AND p_analysis_criteria_id IS NULL)
should be entered. But this is not happening and the program exits after this exception block after entering the exception block.

A hint might be:
The first select will not raise any exception if it gets no result. If it gets no result then the for-loop just won't be entered, so the only thing that will happen is the commit.
(The select inside the for-loop will raise an exception if it gets 0 rows or more than 1 row. The reason is 'select ... into ...': When using 'into' the select must return exact 1 row.)

Related

Multiple APEX_PUBLIC_USER sessions

I have an ORACLE database and ORACLE APEX 5.1 is installed there.
It has worked well in previous days.
In recent days, the server has crashed due to many sessions generated by the user APEX_PUBLIC_USER.
Seeing the current statement, this:
/* Formatted on 30/12/2022 05:19:20 p. m. (QP5 v5.336) */
DECLARE
rc__ NUMBER;
simple_list__ OWA_UTIL.vc_arr;
complex_list__ OWA_UTIL.vc_arr;
BEGIN
OWA.init_cgi_env ( :n__, :nm__, :v__);
HTP.HTBUF_LEN := 63;
NULL;
NULL;
simple_list__ (1) := 'sys.%';
simple_list__ (2) := 'dbms\_%';
simple_list__ (3) := 'utl\_%';
simple_list__ (4) := 'owa\_%';
simple_list__ (5) := 'owa.%';
simple_list__ (6) := 'htp.%';
simple_list__ (7) := 'htf.%';
simple_list__ (8) := 'wpg_docload.%';
simple_list__ (9) := 'ctxsys.%';
simple_list__ (10) := 'mdsys.%';
IF ( (wwv_flow_epg_include_modules.authorize ('wwv_flow.ajax') = FALSE)
OR (owa_match.match_pattern (p_string => 'wwv_flow.ajax'/* */
,
p_simple_pattern => simple_list__,
p_complex_pattern => complex_list__,
p_use_special_chars => FALSE)))
THEN
rc__ := 2;
ELSE
NULL;
NULL;
wwv_flow.ajax (p_flow_id => :p_flow_id,
p_flow_step_id => :p_flow_step_id,
p_instance => :p_instance,
p_debug => :p_debug,
p_request => :p_request,
p_json => :p_json);
IF (WPG_DOCLOAD.is_file_download)
THEN
rc__ := 1;
WPG_DOCLOAD.get_download_file ( :doc_info);
NULL;
NULL;
NULL;
COMMIT;
ELSE
rc__ := 0;
NULL;
NULL;
NULL;
COMMIT;
OWA.get_page ( :data__, :ndata__);
END IF;
END IF;
:rc__ := rc__;
END;
I delete the sessions and they are recreated.
What solution could it be?
Migrate from DB?
New version of APEX?

create list with value from ldap oracle apex

i would like to create a list with data from ldap directory.
I want to be able to display this list and go through this list to select a user from the list.
I have already read about pipeline functions that can return a list (can I as well retrieve data from ldap with such a function?). Another function can then be used to start a search through the list.
I haven't had much to do with ldap so far and would be grateful for any hints and yes in our system we use ldap for authentication.
create object type:
create or replace type ldap_user_ot as object
(email varchar2(30),
username varchar2(30),
firstname varchar2(256),
lastname varchar2(256),
uuid number);
create nested table type:
create or replace type ldap_user_nt as table of ldap_user_ot;
create table function
create or replace function get_user_from_ldap (
p_container IN VARCHAR2 DEFAULT ',ou=users,dc=my-company,dc=en')---what to enter here???
return ldap_user_nt
PIPELINED
IS
l_retval PLS_INTEGER;
l_session dbms_ldap.SESSION;
l_attrs dbms_ldap.string_collection;
l_message dbms_ldap.message;
l_entry dbms_ldap.message;
l_attr_name VARCHAR2(256);
l_ber_element dbms_ldap.ber_element;
l_vals dbms_ldap.string_collection;
l_user ldap_user_ot:=ldap_user_ot(NULL,NULL,NULL,NULL,NULL);
begin
--IF p_ad_group IS NOT NULL THEN lv_retval := -1; ----what to enter here? do I need if statement since I want to return all users
-- Choose to raise exceptions.
dbms_ldap.use_exception := TRUE;
-- Connect to the LDAP server.
l_session := dbms_ldap.Init(hostname => l_ldap_host,
portnum => l_ldap_port)
;
l_retval := dbms_ldap.Simple_bind_s(ld => l_session, dn => v_un,
passwd => p_password);
-- Get all attributes
l_attrs(1) := '*';
l_retval := dbms_ldap.Search_s(ld => l_session, base => l_ldap_base, scope
=>
dbms_ldap.scope_subtree,
filter => '(&(objectclass=posixAccount)(uid='
||p_user_name
||'))', attrs => l_attrs, attronly => 0, res => l_message);
IF dbms_ldap.Count_entries(ld => l_session, msg => l_message) > 0 THEN
v_tableresult := 1;
-- Get all the entries returned by our search.
l_entry := dbms_ldap.First_entry(ld => l_session, msg => l_message);
<< entry_loop >>
WHILE l_entry IS NOT NULL LOOP
-- Get all the attributes for this entry.
dbms_output.Put_line('---------------------------------------');
l_attr_name := dbms_ldap.First_attribute(ld => l_session,
ldapentry => l_entry,
ber_elem => l_ber_element);
<< attributes_loop >>
WHILE l_attr_name IS NOT NULL LOOP
-- Get all the values for this attribute.
l_vals := dbms_ldap.Get_values (ld => l_session,
ldapentry => l_entry,
attr
=>
l_attr_name
);
<< values_loop >>
FOR i IN l_vals.first .. l_vals.last LOOP
CASE l_attr_name
WHEN 'mail' THEN
v_email := Substr(L_vals(i), 1, 200);
WHEN 'givenName' THEN
v_firstname := Substr(L_vals(i), 1, 200);
WHEN 'uid' THEN
v_username := Substr(L_vals(i), 1, 200);
WHEN 'sn' THEN
v_lastname := Substr(L_vals(i), 1, 200);
ELSE
dbms_output.Put_line('ATTIBUTE_NAME: '
|| l_attr_name
|| ' = '
|| Substr(L_vals(i), 1, 200));
END CASE;
END LOOP values_loop;
l_attr_name := dbms_ldap.Next_attribute(ld => l_session,
ldapentry => l_entry,
ber_elem => l_ber_element);
END LOOP attibutes_loop;
l_entry := dbms_ldap.Next_entry(ld => l_session, msg => l_entry);
PIPE ROW(l_user);
END LOOP entry_loop;
END IF;
l_retval := dbms_ldap.Unbind_s(ld => l_session);
end if;
return;
EXCEPTION WHEN no_data_needed THEN
-- unbind from the directory
l_retval := dbms_ldap.Unbind_s(ld => l_session);
return;
WHEN others THEN
IF l_session IS NOT NULL THEN
l_retval := dbms_ldap.Unbind_s(ld => l_session);
END IF;
RAISE;
END get_user_from_ldap;

Item Query From Table and Send It To Procedure

Note
I want to query page item name and send the corresponding items value into a procedure. I can get the item name but couldn't get the value of it. At first I use the following code:
begin
for j in (select item_name from UTLITMINF where service_id ='abc' ) loop
val := val || ':' || j.item_name; --items name
END LOOP;
/* exe := ' begin
dynamic_api_call(p_service => :ser,
p_par => :v_val, --items value to need to send
o_result_json => :v_l_response_text);
end; ';
execute immediate exe
using IN ser,
in val,
out l_response_text;*/
begin
dynamic_api_call(p_service => 'abc',
p_par => val, --items name from page queried from table and send its value to procedure
o_result_json => l_response_text);
end;
raise_application_error(-20001,l_response_text);
end;
In val parameter it contains P11_CUSTOMER. But the value of it did not pass through the procedure. How can I get the value of it? Suggest me if i need to improve my code.
You can use the V (short for value) and NV (short for numeric value) function for dynamic item names. Try something like this (you'll need to adjust on your end).
declare
l_response_text varchar2(255);
l_ser varchar2(255) := 'abc';
l_item_name varchar2(255);
begin
select item_name
into l_item_name
from UTLITMINF
where service_id = l_ser;
dynamic_api_call(
p_service => l_ser,
p_par => v(l_item_name),
o_result_json => l_response_text
);
end;
Try the dynamic sql like the below
begin
for j in (select item_name from UTLITMINF where service_id ='abc' ) loop
val := val || ':' || j.item_name; --items name
END LOOP;
exe := ' begin
dynamic_api_call(p_service => :ser,
p_par => :v_val, --items value to need to send
o_result_json => :v_l_response_text);
end ;';
execute immediate exe
using ser,
val,
OUT l_response_text;
raise_application_error(-20001,l_response_text);

Update: Function Error: PLS-00306: wrong number or types of arguments in call to 'get_bus_result_attribute'

I just think the problem of issue and change the function-to-function logic design. Then, the error as mentioned the function (get_result_attribute) - PLS-00306: wrong number or types of arguments in call to 'get_result_attribute'. May I know the function "get_result_attribute" problem in which part?
Coding for the bus station system.
FUNCTION get_bus_result_attribute (iv_result_name varchar2,
iv_result_key varchar2,
iv_result_attribute varchar2)
--define the parameter to get the "sql_result" script result
RETURN varchar2 IS
sql_result varchar2(500);
sql_return varchar2(500);
BEGIN
sql_result := 'SELECT ' || iv_result_attribute || '
FROM MyTable a,
MyTable b
WHERE a.bus_value_set_id = b.bus_value_set_id
AND b.bus_value_set_name = iv_result_name
AND a.enabled_flag = ''Y''
AND a.bus_value = iv_result_key
AND iv_result_name = get_bus_code (v_bus)
AND iv_result_key = get_bus_name(v_group)
AND iv_result_key = iv_result_attribute';
EXECUTE IMMEDIATE sql_result
INTO sql_return; --get the "sql_result" script result
return sql_return;
exception
when others then
return '';
end get_bus_result_attribute;
FUNCTION get_bus_code (v_bus varchar2)
RETURN VARCHAR2 IS
v_get_bus_code_result VARCHAR2(20) ;
BEGIN
SELECT busa.bus_code
INTO v_get_bus_code_result
FROM tbl_bus_code busa, tbl_bus_line busb
WHERE busa.bus_code_set_id = busb.bus_code_set_id
AND busb.bus_line_set_name = 'HK_BUS_CODE'
AND busa.enabled_flag = 'Y'
AND (busa.attribute4 = 'Y' OR busa.attribute5 = 'Y')
AND busa.BUS_VALUE = v_bus;
RETURN v_get_bus_code_result;
RETURN get_result_attribute('BUS_LINES', v_bus, 'attribute1'); /*BUS_GP*/
EXCEPTION
WHEN OTHERS THEN
RETURN '';
END get_bus_code;
FUNCTION get_bus_name(v_group VARCHAR2) --define the parameter and enter the value in the function 'get_bus_result_attribute'
RETURN VARCHAR2 IS
v_get_bus_div_result VARCHAR2(20) ;
BEGIN
SELECT DISTINCT CASE busa.bus_code --Bus code
WHEN '52' THEN '52X'
WHEN '58P' THEN '58'
WHEN 'K1' THEN 'K1C'
WHEN '40' THEN '40X'
WHEN '6' THEN '6X'
WHEN '7' THEN '7'
WHEN '58M' THEN '58'
ELSE ''
END bus_code --Bus code
INTO v_get_bus_div_result
FROM tbl_bus_code busa, tbl_bus_line busb
WHERE busa.bus_code_set_id = busb.bus_code_set_id
AND busb.bus_line_set_name = 'HK_BUS_LINES'
AND busa.enabled_flag = 'Y'
AND (busa.attribute4 = 'Y' OR busa.attribute5 = 'Y')
AND busa.bus_code NOT IN ('INACTIVE', 'XXX')
AND get_bus_code(busa.BUS_VALUE) = v_group
RETURN get_result_attribute('BUS_GROUP', v_group, 'attribute2');
--bus_group_dir
EXCEPTION
WHEN OTHERS THEN
RETURN '';
END get_bus_name;
FUNCTION BUS_DOC_TEXT (N_ID NUMBER, N_HEAD_ID NUMBER)
RETURN VARCHAR2 IS
v_bus_doc_text VARCHAR2(150);
BEGIN
SELECT 'BUS\'
|| get_bus_result_attribute(abc.attribute14)
|| '\'
|| abc.attribute14
|| '\'
|| abc.segment1
INTO v_bus_doc_text
FROM my_table_c abc
WHERE abc.ORG_ID = N_ID -- parameter
AND abc.bus_id = N_HEADER_ID; -- parameter
END;
RETURN v_bus_doc_text ;
END;
END;

Plsql to spell number (currency) to Italian currency without hardcoded the translation number

I could not find a post to do it automatically as I don't want to hard coded the mapping between English to Italian.
Is there any way to write the spelling number to any language in PLSQL, Oracle 10g or 11i ?
I do not have this built in package: AP_AMOUNT_UTILITIES_PKG in my oracle.
CREATE OR REPLACE FUNCTION Currency_conversion(currency IN NUMBER)
RETURN VARCHAR2 IS
txt varchar2(4000);
tlum varchar2(4000);
babelTxt varchar(32000);
req utl_http.req;
resp utl_http.resp;
webtext VARCHAR2(4000);
webextract VARCHAR2(4000);
BEGIN
-- This is used to convert number to words in english
SELECT CAST( to_char( to_timestamp( lpad(currency,9,'0'), 'FF9' ), 'FFSP' ) AS VARCHAR2(100) )
into txt from dual;
-- FFSP is used to spell Fraction second in words for example HH24SP
-- can be used to spell hours from 0 to 23,i used FFSP to get max range
txt:=translate(txt,'x-','x ');
-- The below logic is taken from
-- https://forums.oracle.com/forums/thread.jspa?threadID=1122273(and)start=15(and) tstart=0
--need to test once
-- request that exceptions are raised for error status codes
utl_http.set_response_error_check(enable => TRUE);
-- allow testing for exceptions like Utl_Http.Http_Server_Error
utl_http.set_detailed_excp_support(enable => TRUE);
txt:=utl_url.escape(txt);
babelTxt := 'http://babelfish.yahoo.com/translate_txt?doit=done' || '&' || 'lp=en_it' || '&' || 'intl=1' || '&' || 'ei=utf8' || '&' || 'trtext=' || txt;
req:=utl_http.begin_request(url => babelTxt, method => 'GET');
resp := utl_http.get_response(r => req);
BEGIN
LOOP
--utl_http.read_text(r => resp, data => webtext, len => 32767);
utl_http.read_line(r => resp , data => webtext);
webextract := regexp_substr(webtext,'<div id="result"><div style="padding:0.6em;">(.+)</div></div>');
if webextract is not null
then
select regexp_replace(webextract,'<div id="result"><div style="padding:0.6em;">(.+)</div></div>','\1')
into tlum FROM dual;
end if;
exit when tlum is not null;
END LOOP;
EXCEPTION
WHEN utl_http.end_of_body THEN
NULL;
END;
utl_http.end_response(r => resp);
return tlum;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line(SQLERRM);
return '';
END;
/
exit;

Resources