ORA-29263 thrown error ONLY when URL becomes LONG - oracle

I am trying to call a restful service from my ora pkg; Sometimes with the same code, this service is reached successfully and a response is returned; but when the message in the url becomes longer ==> ORA-29273 http request and ORA-29263 http protocol are thrown; I do not change anything between calls, only messages to be sent from this URL; Below is my procedure:
PROCEDURE SEND_SMS(username VARCHAR2,
password VARCHAR2,
phone VARCHAR2,
message VARCHAR2,
code VARCHAR2,
P_RESPONSE OUT VARCHAR2) AS
v_request UTL_HTTP.req;
v_response UTL_HTTP.resp;
v_text VARCHAR2(1024);
v_url VARCHAR2(1024);
v_message VARCHAR2(1024);
BEGIN
BEGIN
P_RESPONSE := '';
v_message := REPLACE(message,' ', '%20');
v_url := 'http://myservicelink.com/SendSMS?strUsername=' |
username || '&strPassword=' || password ||
'&strPhone=' || phone || '&strcode=' || code ||
'&strMessage=' || v_message;
v_request := UTL_HTTP.begin_request(v_url);
DBMS_OUTPUT.put_line(v_url);
v_response := UTL_HTTP.get_response(v_request);
LOOP
BEGIN
UTL_HTTP.read_text(v_response, v_text);
DBMS_OUTPUT.put_line(v_text);
EXCEPTION
WHEN UTL_HTTP.end_of_body THEN
NULL;
END;
EXIT WHEN v_text IS NULL;
END LOOP;
UTL_HTTP.end_response(v_response);
IF v_response.status_code <> 200 THEN
P_RESPONSE := v_response.reason_phrase;
END IF;
EXCEPTION
WHEN OTHERS THEN
P_RESPONSE := 'An error has occured: ' || SQLERRM;
END;
END SEND_SMS;
So when v_message becomes longer, exception is thrown. What can be the error; Please note that the same link is called from outside ORA pkg with same inputs --> myservice is reached;
Here is a template of my working message:
Dear X, you have been registered to our app. You can download the app for iPhone at link of app store or for android at link of
Not working:
Dear X, you have been registered to our app. You can download the app for iPhone at link of app store or for android at link of play store
your

The difference between your two strings isn't just length; the second one has a newline character in it as well. You are replacing spaces using:
v_message := REPLACE(message,' ', '%20');
but that won't deal with any other illegal characters.
If you change that to use the utl_url.escape() function:
v_message := utl_url.escape(message);
then it will escape the new line as well, so you end up with this for the first message (same as your current code gives):
Dear%20X,%20you%20have%20been%20registered%20to%20our%20app.%20You%20can%20download%20the%20app%20for%20iPhone%20at%20link%20of%20app%20store%20or%20for%20android%20at%20link%20of
but this for the second:
Dear%20X,%20you%20have%20been%20registered%20to%20our%20app.%20You%20can%20download%20the%20app%20for%20iPhone%20at%20link%20of%20app%20store%20or%20for%20android%20at%20link%20of%20play%20store%0Ayour
The newline has been encoded as %0A. Depending on what else is in the message, you may need to pass true as the second argument instead of letting it default to false; the difference is explained in the documentation link above.

Related

"ORA-29024: Certificate validation failure"

I am trying to consume Rest API in oracle procedure. I have created ACL entry as well as Added the SSL certificate to my oracle wallet manager. but when i am trying to execute the procedure i am getting the error as "ORA-29024: Certificate validation failure". Following is the code for my oracle procedure.
create or replace procedure TABADUL_TAS_AUTHENTICATION
is
req utl_http.req;
res utl_http.resp;
value VARCHAR2(1024);
value1 VARCHAR2(1024);
url varchar2(4000) := 'https://tapis.fasah.sa/tabadul/fasahqa/authorization/token';
name varchar2(4000);
buffer varchar2(4000);
content varchar2(4000) := '{"username":"ijsnj001","password":"P#ssw0rd"}';
begin
UTL_HTTP.set_wallet('file:d:\tabadul', 'tas123456');
req := utl_http.begin_request(url, 'POST',' HTTP/1.1');
utl_http.set_header(req, 'user-agent', 'mozilla/4.0');
utl_http.set_header(req, 'content-type', 'application/json;charset=utf-8');
utl_http.set_header(req,'X-IBM-Client-Id','00a2f36e933e2bb9edc76faaf26659eb');
utl_http.set_header(req,'X-IBM-Client-Secret','7c2829bd6b287b072ee269c9ad8f5ead');
utl_http.set_header(req,'Accept-Language','en');
utl_http.set_header(req,'Accept','application/json');
utl_http.set_header(req, 'Content-Length', length(content));
utl_http.write_text(req, content);
res := utl_http.get_response(req);
-- process the response from the HTTP call
DBMS_OUTPUT.PUT_LINE('HTTP response status code: ' || res.status_code);
--DBMS_OUTPUT.PUT_LINE('HTTP response reason phrase: ' || res.reason_phrase);
FOR i IN 1..UTL_HTTP.GET_HEADER_COUNT(res) LOOP
UTL_HTTP.GET_HEADER(res, i, name, value1);
--DBMS_OUTPUT.PUT_LINE(name || ': ' || value1);
END LOOP;
--dbms_output.put_line(content);
--dbms_output.put_line(utl_http.resp);
begin
loop
--dbms_output.put_line('A');
utl_http.read_line(res, value, true);
--dbms_output.put_line(length(value));
dbms_output.put_line(value);
--INSERT INTO A VALUES (VALUE);
--COMMIT;
end loop;
utl_http.end_response(res);
exception
when utl_http.end_of_body
then
--dbms_output.put_line(SQLCODE||','||SQLERRM);
utl_http.end_response(res);
when others then
--dbms_output.put_line(SQLCODE||','||SQLERRM);
utl_http.end_response(res);
end;
end TABADUL_TAS_AUTHENTICATION;
This issue has been resolved.I am writing the solution here, it might be helpful for others.
So instead of creating wallet for the actual website certificate, need to create wallet only for chain of certificate.

Error executing DBMS_OUTPUT.PUT_LINE in Oracle

I am running DBMS_OUTPUT.PUT_LINE to send a message from a procedure and I am trying to display the debug information of what a type variable contains BFILE
create or replace PROCEDURE P_FILEUPLOAD_XML IS
v_dir gzvcatg.gzvcatg_desc11%TYPE;
l_dir VARCHAR2(35);
l_fil VARCHAR2(30) := 'ES0000251446027471.xml';
l_loc BFILE;
BEGIN
l_loc := BFILENAME(v_dir,l_fil);
DBMS_OUTPUT.PUT_LINE(l_loc);
END;
At the moment of executing my procedure and waiting for a response from the log:
Anyone know why the error is due and how to correct it.
UPDATE:
Following the recommendation in the MT0 response making use of DBMS_LOB.READ, try the following:
create or replace PROCEDURE P_FILEUPLOAD_XML IS
v_dir gzvcatg.gzvcatg_desc11%TYPE;
l_dir VARCHAR2(35);
l_fil VARCHAR2(30) := 'ES0000251446027471.xml';
l_loc BFILE;
BEGIN
l_loc := BFILENAME(v_dir,l_fil);
DBMS_LOB.READ(l_loc IN BFILE);
END;
But executing it generates the following error:
Anyone know why the error is due
l_loc is a BFILE.
DBMS_OUTPUT.PUT_LINE( item IN VARCHAR2 ) takes a VARCHAR2 data type as its argument.
You cannot implicitly cast a BFILE to a VARCHAR2 so the procedure call raise an exception as it is the wrong type of argument to call the function with.
and how to correct it.
Read the file using DBMS_LOB.READ and use UTL_RAW.CAST_TO_VARCHAR2 to convert the RAW value you get from the LOB to a string so you can print it.

Consuming rest API from Oracle PLSQL is returning ??? for arabic characters

I am trying to call a restful API from my Oracle procedure.
First, the API method is of type get and not post, so parameters are sent through header. the main purpose of the API is to send the received message as SMS to some providers and sometimes they are in Arabic format; We realized that Arabic received SMS are incomprehensible;
So I created a test procedure that takes a message and sends it to a test API method that returns the same message as response.
The API call succeeded but the response, only when arabic format is used, looks like ����. What should be added to my procedure so messages can be readable? I have tried to use escape for the message and to set the header format as you can see in below template, but unfortunately nothing succeeded:
PROCEDURE TEST(lang VARCHAR2,
message VARCHAR2,
P_RESPONSE OUT VARCHAR2) AS
v_request UTL_HTTP.req;
v_response UTL_HTTP.resp;
v_text VARCHAR2(1024);
v_url VARCHAR2(1024);
v_message VARCHAR2(1024);
l_webservice_link VARCHAR2(128);
BEGIN
BEGIN
P_RESPONSE := '';
v_message := utl_url.escape(message);
--v_message :=utl_url.escape(message,false,'UTF-8');
--v_message :=utl_url.escape(message,false,'windows-1256');
--v_message :=utl_url.escape(message,false,'AL32UTF8');
--v_message :=utl_url.escape(message,false,'AR8MSWIN1256');
l_webservice_link := GET_PARAM('REST_API_URL');
v_url := l_webservice_link ||
'Mytest?strMessage=' || v_message||
'&strLang=' || lang;
v_request := UTL_HTTP.begin_request(v_url);
--UTL_HTTP.set_header(v_request, 'Content-Type', 'charset=UTF-8');
--UTL_HTTP.set_header(v_request, 'Content-Type', 'windows-1256');
v_response := UTL_HTTP.get_response(v_request);
LOOP
BEGIN
UTL_HTTP.read_text(v_response, v_text);
DBMS_OUTPUT.put_line(v_text);
EXCEPTION
WHEN UTL_HTTP.end_of_body THEN
NULL;
END;
EXIT WHEN v_text IS NULL;
END LOOP;
UTL_HTTP.end_response(v_response);
IF v_response.status_code <> 200 THEN
P_RESPONSE := v_response.reason_phrase;
END IF;
EXCEPTION
WHEN OTHERS THEN
P_RESPONSE := 'An error has occured: ' || SQLERRM;
END;
END TEST;
Any help is more than appreciated.
Try to insert this code:
Charset VARCHAR2(20);
BEGIN
SELECT UTL_I18N.MAP_CHARSET(VALUE)
INTO Charset
FROM nls_database_parameters
WHERE parameter = 'NLS_CHARACTERSET';
UTL_HTTP.set_header(v_request, 'Content-Type', 'text/html; charset='||Charset);
I am not familiar with REST, I don't know wether text/html; is required and correct.
Update
I just see your database character set it AR8ASMO8X which does not have any IANA name (at least not according to Oracle UTL_I18N.MAP_CHARSET)
In this case try
UTL_HTTP.set_header(v_request, 'Content-Type', 'text/html; charset=UTF-8');
UTL_HTTP.begin_request(CONVERT(v_url,'AL32UTF8'));
Most likely the server returns response in UTF-8 - would be the most common one, otherwise check the header of the response.
Then try this:
UTL_HTTP.SET_BODY_CHARSET(v_response, 'AL32UTF8');
Apart from all above you may have also a display issue, i.e. inside Oracle everything would be fine, just your client is not able to display the characters properly, see OdbcConnection returning Chinese Characters as "?"

REP-501: Unable to connect to the specified database.

I need to implement the functionality of generating a report from some parameters that the user introduces through an Oracle Forms application.
The utility is built into a code unit inside the form:
PACKAGE BODY INVOICES_MANAGEMENT IS
-- Generate Invoices Report
PROCEDURE GENERATE_INVOICES_REPORT (
P_REPORTNAME IN VARCHAR2,
P_FORMAT IN VARCHAR2,
P_REPORT_SERVER IN VARCHAR2,
P_MINYEAR IN INTEGER,
P_MAXYEAR IN INTEGER) IS
v_report_id Report_Object;
-- Unique id for each Report request
v_report_server_job VARCHAR2(100);
-- Status of the Report job
v_rep_status VARCHAR2(100);
-- job_id as number only string
v_job_id VARCHAR2(100);
-- Param List
v_tmp_plid ParamList;
v_hidden_action VARCHAR2(200);
BEGIN
v_tmp_plid := Get_Parameter_List('RepData');
IF NOT ID_NULL(v_tmp_plid) THEN
DESTROY_PARAMETER_LIST( v_tmp_plid );
END IF;
v_tmp_plid := CREATE_PARAMETER_LIST ('RepData');
-- Get a handle to the Report Object
v_report_id := FIND_REPORT_OBJECT(P_REPORTNAME);
/* Define the report output format and the name of the Reports Server as well as a user-defined parameter. */
SET_REPORT_OBJECT_PROPERTY(v_report_id, REPORT_DESFORMAT, P_FORMAT);
SET_REPORT_OBJECT_PROPERTY(v_report_id, REPORT_DESTYPE, CACHE);
SET_REPORT_OBJECT_PROPERTY(v_report_id, REPORT_COMM_MODE, SYNCHRONOUS);
SET_REPORT_OBJECT_PROPERTY(v_report_id, REPORT_SERVER, P_REPORT_SERVER);
--SET_REPORT_OBJECT_PROPERTY(v_report_id, REPORT_OTHER, 'MIN_YEAR='||P_MINYEAR||' MAX_YEAR=' || P_MAXYEAR || ' paramform=no');
Add_Parameter(v_tmp_plid, 'MIN_YEAR', TEXT_PARAMETER, P_MINYEAR );
Add_Parameter(v_tmp_plid, 'MAX_YEAR', TEXT_PARAMETER, P_MAXYEAR );
v_hidden_action := 'userid=' ||
--get_application_property(username)
'sergio11' || '/' ||
--get_application_property(password)
'bisite00' || '#' || 'XE';
--get_application_property(connect_string);
MESSAGE('HIDE ACTION -> ' || v_hidden_action);
SET_REPORT_OBJECT_PROPERTY (v_report_id, REPORT_OTHER, v_hidden_action);
-- Run Report
v_report_server_job := RUN_REPORT_OBJECT(v_report_id, v_tmp_plid);
v_job_id := substr(v_report_server_job, instr(v_report_server_job, '_' , -1)+1);
LOOP
v_rep_status := REPORT_OBJECT_STATUS(v_report_server_job);
EXIT WHEN v_rep_status IN ('FINISHED', 'TERMINATED_WITH_ERROR');
END LOOP;
IF v_rep_status = 'FINISHED' THEN
/* Call the Reports output to be displayed in the browser. The URL for relative addressing is valid
only when the Reports Server resides on the same host as the Forms Server and is accessed via the same port.
For accessing a remote Reports environment, you must use a fully qualified URL (i.e. http://hostname:port ) */
WEB.SHOW_DOCUMENT ('/reports/rwservlet/getjobid'|| v_job_id || '?server='|| P_REPORT_SERVER, '_blank');
ELSE
MESSAGE('Report failed with error message '|| v_rep_status);
END IF;
END;
END;
This procedure will be executed when using the "Generate" button, then the user should be able to download the pdf file with the list of invoices.
Next I expose the code for SmartTrigger 'WHEN-BUTTON-PRESSED'
DECLARE
v_minyear INTEGER;
v_maxyear INTEGER;
v_reportname VARCHAR2(30) DEFAULT 'INVOICES_REPORT';
v_format VARCHAR2(10) DEFAULT 'PDF';
v_reportserver VARCHAR2(15) DEFAULT 'rep_ie8win7';
BEGIN
v_minyear := :MIN_YEAR_TEXT;
v_maxyear := :MAX_YEAR_TEXT;
-- Generate Invoice Report
INVOICES_MANAGEMENT.GENERATE_INVOICES_REPORT ( v_reportname, v_format,
v_reportserver, v_minyear, v_maxyear);
END;
The answer is immediate, "FRM - 41214 Unable to run report" is throw with a TERMINATED_WITH_ERRORS state.
When consulting the status of the "job" launched from the Oracle Forms application, I find that the source of the problem is an error "REP-501: Unable to connect to the specified database."
Considerations
I have a TNS_ADMIN environment variable configured to locate the
files for the Oracle NET layer (tnsnames.ora)
TNS_ADMIN -> C:\oraclexe\app\oracle\product\11.2.0\server\network\ADMIN
From Oracle Reports Builder I can correctly generate the report, I
have exported this report as a binary file ".rep" to include it as a
"report" object in the form.
I have tried to provide the complete connection string through the
userid parameter.
SET_REPORT_OBJECT_PROPERTY (v_report_id, REPORT_OTHER, 'userid=' || get_application_property(username) || '/' || get_application_property(password) || '#' || get_application_property(connect_string));
I am using Oracle Application Server 10g.
Can someone help me solve this problem?
Thank you

TRIGGER BEFORE A COMMIT (INSERT OR UPDATE)

I have a trigger that calls a webservice link.
This link read a View, and that view is composing a XML.
The problema is:
The trigger is executed when I have a cod_situation = 6 like this:
CREATE OR REPLACE TRIGGER trg_candidato_chama_link
AFTER INSERT OR UPDATE ON cand_proc_sel
FOR EACH ROW DECLARE
v_url VARCHAR2(4000);
req UTL_HTTP.REQ;
resp UTL_HTTP.RESP;
value VARCHAR2(1536);
--temp
v_count INTEGER;
v_alternativas VARCHAR2(1000);
v_error VARCHAR2(4000);
BEGIN
if (:new.cod_situation = 6 ) THEN
v_url := 'http://.../frameweb/amxv7/amx_new_employee';
req := UTL_HTTP.BEGIN_REQUEST(v_url);
UTL_HTTP.SET_HEADER(req, 'User-Agent', 'Mozilla/4.0');
resp := UTL_HTTP.GET_RESPONSE(req);
LOOP
UTL_HTTP.READ_LINE(resp, value, TRUE);
DBMS_OUTPUT.PUT_LINE(value);
END LOOP;
UTL_HTTP.END_RESPONSE(resp);
END IF;
EXCEPTION WHEN UTL_HTTP.END_OF_BODY THEN
UTL_HTTP.END_RESPONSE(resp);
INSERT INTO integratio_log(data, cod_integracao, status, rotina, obs) VALUES(SYSDATE, 7, 'SUCCESS', 'TEST DOM, TRIGGER URL', 'Url : ' || v_url || ' count test: '|| v_count); WHEN OTHERS THEN
v_error := To_Char(SQLERRM);
INSERT INTO integracao_log(data, cod_integracao, status, rotina, obs) VALUES(SYSDATE, 7, 'FAIL', 'TEST DOM, TRIGGER URL', 'Url : ' || v_url || ' # qtd: '|| v_count || ' # Erro: ' || v_error);
END;
But, the problem is:
the clause where in the View is just the condition cod_situation = 6, but when the trigger calls the webservice where we read the View, I do not have cod_situation = 6 yet.
So, my question is, how can I call the trigger link, but only after the commit is done in the table?
A post commit hook is not available. And this is for good reason: At the point where you access the web service the modified data has already been committed. What should the database do if the commit is successful but the post commit fails?
Generally speaking it is not a good idea to access other systems from a trigger: Your session is still not committed hence a rollback is possible. That would means that your web service has been informed about a transaction in the database that might never be written to disk. This may or may not be catastrophic. Additionally you make the functionality of your database dependent on the availability of the web service which is bad practice in itself.
If you absolutely have to do what you are doing you would do yourself a favor by moving the view reading into a stored procedure and call that from the trigger and the web service.

Resources