invoke a webservice through pl/sql block - sql

How to invoke a webservice through pl/sql block for which we know url,username and password.
And how to see the response?
Give some sample code...
Thanks in advance
I have used the following piece of code:
CREATE OR REPLACE FUNCTION READ_DATA_FROM_WS (url IN VARCHAR2,
username IN VARCHAR2,
password IN VARCHAR2)
RETURN CLOB
IS
req UTL_HTTP.req;
resp UTL_HTTP.resp;
DATA VARCHAR2 (2000);
data1 CLOB;
def_timeout PLS_INTEGER;
l_envelope VARCHAR2(32767);
BEGIN
req := utl_http.begin_request(url, 'POST','HTTP/1.0');
UTL_HTTP.set_authentication (req, username, password);
utl_http.set_header(req, 'Content-Type', 'text/xml');
resp := utl_http.get_response(req);
IF (resp.status_code = UTL_HTTP.http_ok)
THEN
UTL_HTTP.set_body_charset (resp, 'UTF-8');
BEGIN
LOOP
UTL_HTTP.read_text (resp, DATA);
data1 := data1 || DATA;
END LOOP;
EXCEPTION
WHEN UTL_HTTP.end_of_body
THEN
UTL_HTTP.end_response (resp);
UTL_HTTP.set_transfer_timeout (def_timeout);
WHEN OTHERS
THEN
NULL;
END;
UTL_HTTP.set_transfer_timeout (def_timeout);
ELSE
UTL_HTTP.end_response (resp);
DBMS_OUTPUT.put_line ('HTTP response status code: ' || resp.status_code);
END IF;
RETURN (data1);
END read_data_from_ws;
/

I have used web services with pl/sql without problems!
I'm using this one (+ my own improvements): http://www.oracle-base.com/dba/miscellaneous/soap_api.sql
Be sure that you define name spaces correctly, and I think you should only use this for retrieving ASCII not binary data...

Here is some sample code. Left some pieces out but it gives you an idea. The function returns the capabilities XML for a WMS webservice.
function getcapabilities(p_url varchar2
,p_version varchar2) return xmltype is
pragma autonomous_transaction;
req utl_http.req;
resp utl_http.resp;
c varchar2(255);
l_clob clob;
begin
dbms_lob.createtemporary(lob_loc => l_clob, cache => true, dur => dbms_lob.call);
-- -----------------------------------
-- OPEN TEMPORARY LOB FOR READ / WRITE
-- -----------------------------------
dbms_lob.open(lob_loc => l_clob, open_mode => dbms_lob.lob_readwrite);
utl_http.set_proxy(proxy => <proxy>, no_proxy_domains => <no_proxy>);
/* 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);
if instr(p_url, '?') > 0
then
req := utl_http.begin_request(p_url || '&REQUEST=GetCapabilities&SERVICE=WMS&VERSION=' ||
p_version);
else
req := utl_http.begin_request(p_url || '?REQUEST=GetCapabilities&SERVICE=WMS&VERSION=' ||
p_version);
end if;
utl_http.set_header(req, 'User-Agent', 'Mozilla/4.0');
resp := utl_http.get_response(req);
begin
loop
utl_http.read_text(r => resp, data => c);
/* function that adds a string to a clob */
add_to_clob(l_clob, c);
end loop;
exception
when utl_http.end_of_body then
null;
when others then
raise;
end;
utl_http.end_response(resp);
dbms_lob.close(lob_loc => l_clob);
/* this was for some Oracle bug */
execute immediate 'alter session set events =''31156 trace name context forever, level 2''';
commit;
return xmltype.createxml(l_clob);
end;

Even if there is a way to do this it would be a very bad practice!
Also, there are so many problems here. What will this service return? How are you gonna parse the results to something that sql can understand? How are you going to handle errors coming back from the service?
Just return whatever it is you need to return to the application and have the app invoke the web service.

Related

function in plsql

I have created this function and it works:
create or replace function log_in(
p_ssnr in customer.ssnr%type,
p_password in customer.password%type)
return number
as
v_number number(1);
begin
if
(p_ssnr is not null and p_password is not null) then
v_number:= 1;
else
v_number:= 0;
end if;
return v_number;
end;
If I then type: select log_in('social security number','the password') from dual; then I get a "1"
so it works. But you could basically type whatever you want and it will work so it is not a clean code. Since you can't include subquery in the if statement, how can you create the function so you only return 1 when you actually type a social security number (ssnr) and a password that matches the actual customer table? and otherwise you return 0?
NOt sure if you can have multiple rows for same customer. If yes, then use this:
create or replace function log_in(
p_ssnr in customer.ssnr%type,
p_password in customer.password%type)
return number
as
v_number number(1);
begin
select case when count(*) > 0 then 1 else 0 end
into v_number
from customer
where ssnr = p_ssnr and password = p_password;
return v_number;
end;
If not then this should be fine:
create or replace function log_in(
p_ssnr in customer.ssnr%type,
p_password in customer.password%type)
return number
as
v_number number(1);
begin
count(*)
into v_number
from customer
where ssnr = p_ssnr and password = p_password;
return v_number;
end;

Oracle Loop by User Name

I found a script that will allow you to End Date a Responsibility by providing the User Name and Responsibility name. I'm trying to figure out how to create this into a loop so that User Name doesn't have to be provided.
Something along the logic of:
if (responsibility exists for user)
end date
else
check next user
Here's the script I've been using to end date via user name:
DECLARE
v_user_name VARCHAR2 (100) := 'PRAJKUMAR';
v_responsibility_name VARCHAR2 (100) := 'Application Developer';
v_application_name VARCHAR2 (100) := NULL;
v_responsibility_key VARCHAR2 (100) := NULL;
v_security_group VARCHAR2 (100) := NULL;
BEGIN
SELECT fa.application_short_name,
fr.responsibility_key,
frg.security_group_key
INTO v_application_name,
v_responsibility_key,
v_security_group
FROM fnd_responsibility fr,
fnd_application fa,
fnd_security_groups frg,
fnd_responsibility_tl frt
WHERE fr.application_id = fa.application_id
AND fr.data_group_id = frg.security_group_id
AND fr.responsibility_id = frt.responsibility_id
AND frt.LANGUAGE = USERENV ('LANG')
AND frt.responsibility_name = v_responsibility_name;
fnd_user_pkg.delresp
( username => v_user_name,
resp_app => v_application_name,
resp_key => v_responsibility_key,
security_group => v_security_group
);
COMMIT;
DBMS_OUTPUT.put_line ( 'Responsiblity '
|| v_responsibility_name
|| ' is removed from the user '
|| v_user_name
|| ' Successfully'
);
END;
/
Reference: https://blogs.oracle.com/prajkumar/end-date-responsibility-for-oracle-fnd-user

Cursor for loop to return output in proper format in oracle stored procedure

I have below procedure in which i want to return the output of variable value brand_name.BRAND_NAME. I am getting the correct output. But i want to return it in proper format. For example right now i am getting the output as
BRAND_NAMES:FNC
BRAND_NAMES:LIDL
But i want to return the output as:
BRAND_NAME: FNC,LIDL
Here is my stored procedure:
FUNCTION BUILD_ALERT_EMAIL_BODY
(
IN_ALERT_LOGS_TIMESTAMP IN TIMESTAMP
, IN_ALERT_LOGS_LOG_DESC IN VARCHAR2
, IN_KPI_LOG_ID IN NUMBER
) RETURN VARCHAR2 AS
BODY VARCHAR2(4000) := '';
V_KPI_DEF_ID NUMBER := '';
V_BRAND_NAME VARCHAR2(100) := '';
V_KPI_TYPE_ID NUMBER := '';
CURSOR brand_names_cur
IS
Select BR.NAME AS BRAND_NAME INTO V_BRAND_NAME FROM RATOR_MONITORING_CONFIGURATION.KPI_DEFINITION KD JOIN RATOR_MONITORING_CONFIGURATION.KPI_DEFINITION_BRAND KDB ON KD.KPI_DEF_ID = KDB.KPI_DEF_ID JOIN
RATOR_MONITORING_CONFIGURATION.BRAND BR ON KDB.BRAND_ID = BR.BRAND_ID WHERE KD.KPI_DEF_ID = V_KPI_DEF_ID;
BEGIN
Select KPI_DEF_ID INTO V_KPI_DEF_ID FROM KPI_LOGS WHERE KPI_LOG_ID = IN_KPI_LOG_ID;
Select KT.KPI_TYPE_ID INTO V_KPI_TYPE_ID FROM RATOR_MONITORING_CONFIGURATION.KPI_DEFINITION KD JOIN RATOR_MONITORING_CONFIGURATION.KPI_TYPE KT ON KD.KPI_TYPE = KT.KPI_TYPE_ID WHERE KD.KPI_DEF_ID = V_KPI_DEF_ID;
FOR brand_name IN brand_names_cur
LOOP
BODY := BODY || 'BRAND_NAME:' || brand_name.BRAND_NAME || Chr(10) || Chr(13);
END LOOP;
BODY := BODY || 'ALERT_DESCRIPTION:' || to_char(IN_ALERT_LOGS_LOG_DESC);
RETURN BODY;
END BUILD_ALERT_EMAIL_BODY;
Add V_FIRST_RECORD variable
V_FIRST_RECORD Boolean := true;
and use it in your loop like this
if v_first_record then
body := 'BRAND_NAME: '||brane_name.BRAND_NAME;
else
body := body ||','||brane_name.BRAND_NAME;
v_first_record := false;
end if;

Updating a record in database

Using TADOCommand to update a record.
using TADOCommand to insert a new record.
Name of table is Board
Using MS Access database
I get an error
Syntax error in UPDATE/INSERT INTO statement
I can connect and retrieve data just fine. Just never added or updated data before.
My database columns looks like this
ID (auto number)
SN (text)
CardType (text)
Desc (memo)
dbDate (date)
Tech (text)
Code looks like this:
procedure TForm2.BSaveClick(Sender: TObject);
const
sqlStringNew = 'INSERT INTO Board (SN,CardType,Desc,dbDate,Tech) VALUES (:aSN,:aCardType,:aDesc,:aDate,:aTech);';
sqlStringUpdate = 'UPDATE Board SET SN=:aSN, CardType=:aCardType, Desc=:aDesc, dbDate=:aDate, Tech=:aTech WHERE ID = :aID;';
var
ADOCommand : TAdoCommand;
begin
ADOCommand := TADOCommand.Create(nil);
// updating a board
if NewBoard = false then
begin
try
ADOCommand.Connection := adoConnection1;
ADOCommand.Parameters.Clear;
ADOCommand.Commandtext := sqlStringUpdate;
ADOCommand.ParamCheck := false;
ADOCommand.Parameters.ParamByName('aSN').Value := ESerialNumber.Text;
ADOCommand.Parameters.ParamByName('aCardType').Value := ECardType.Text;
ADOCommand.Parameters.ParamByName('aDesc').Value := MDescription.Text;
ADOCommand.Parameters.ParamByName('aDate').Value := strtodate(EDate.Text);
ADOCommand.Parameters.ParamByName('aTech').Value := ETech.Text;
ADOCommand.Parameters.ParamByName('aID').Value := UpdateID;
ADOCommand.Execute;
finally
ADOCommand.Free;
end;
Showmessage('Update Complete');
end;
//if a new board
if NewBoard = True then
Begin
try
ADOCommand.Connection := adoConnection1;
ADOCommand.Parameters.Clear;
ADOCommand.Commandtext := sqlStringNew;
ADOCommand.ParamCheck := false;
ADOCommand.Parameters.ParamByName('aSN').Value := ESerialNumber.Text;
ADOCommand.Parameters.ParamByName('aCardType').Value := ECardType.Text;
ADOCommand.Parameters.ParamByName('aDesc').Value := MDescription.Text;
ADOCommand.Parameters.ParamByName('aDate').Value := strtodate(EDate.Text);
ADOCommand.Parameters.ParamByName('aTech').Value := ETech.Text;
ADOCommand.Execute;
finally
ADOCommand.Free;
end;
NewBoard := false;
BSave.Enabled := false;
NoEdit;
Showmessage('New Record Added');
End;
end;
It is advisable not to use SQL keywords for table and field names. DATE is a function in many SQL dialects. If you choose to use a reserved word/function name for a table/field name, you have to escape it in SQL statement: [Date] for SQL Server and MS Access, "Date" - for Oracle.

Why isn't my authentication working? (Apex)

I have a function to authenticate my users, which works because I tested it.
Authenticate function:
create or replace function authenticate(p_username in VARCHAR2, p_password in VARCHAR2)
return BOOLEAN
is
l_password varchar2(4000);
l_stored_password varchar2(4000);
l_count number;
begin
select count(*) into l_count from users where username = p_username;
if l_count > 0 then
-- First, we fetch the stored hashed password
select password into l_stored_password
from users where upper(username) = upper(p_username);
-- we have to apply the custom hash function to the password
l_password := custom_hash(p_username, p_password);
-- Finally, we compare them to see if they are the same and return
-- either TRUE or FALSE
if l_password = l_stored_password then
return true;
else
return false;
end if;
else
-- The username provided is not in the users table
return false;
end if;
end;
Yet my authentication in Apex doesn't work, I activated the authentication scheme and linked to authenticate function.
I'm using apex 4.2
This is how I've got mine setup:
Scheme Type: Custom
Authentication Function Name: my_auth_func
Source:
FUNCTION my_auth_func (p_username IN VARCHAR2, p_password IN VARCHAR2)
RETURN BOOLEAN
IS
is_authenticated BOOLEAN := FALSE;
BEGIN
--authentication logic, etc...
RETURN is_authenticated;
END