assigning a oracle PLSQL variable with URL - oracle

I have a task in which i need to create a rest API call within a stored procedure in Oracle.
I have looked at the following documentation as an example.
https://technology.amis.nl/2015/05/11/invoke-a-rest-service-from-plsql-make-an-http-post-request-using-utl_http-in-oracle-database-11g-xe/
in my PLSQL i am trying to set my url variable to the following string:
https://localhost/access_token?client_id=1234&client_secret=1234&grant_type=client_credentials
using the following
v_url := 'https://localhost/access_token?client_id=1234'||chr(38) ||'client_secret=1234'||chr(38) ||'grant_type=client_credentials';
However the variable is not being set as it is coming back null. The variable can be set up to the point before the '&'
create or replace procedure mule_test( p_clientid in varchar2,
p_clientsecret in varchar2)
AS
req utl_http.req;
res utl_http.resp;
v_url VARCHAR2(255); v_name VARCHAR2(255);
v_buffer varchar2(4000);
v_content varchar2(4000);
begin
v_url := 'https://localhost/access_token?client_id=1234'||chr(38)
||'client_secret=1234'||chr(38) ||'grant_type=client_credentials';

Works OK for me:
SQL> set serveroutput on
SQL> declare
2 v_url varchar2(200);
3 begin
4 v_url := 'https://localhost/access_token?client_id=1234'||chr(38) ||'client_secret=1234'||chr(38) ||'grant_type=client_credentials';
5 dbms_output.put_line(v_url);
6 end;
7 /
https://localhost/access_token?client_id=1234&client_secret=1234&grant_type=client_credentials
PL/SQL procedure successfully completed.
SQL>

Related

PLSQL variable doesn't get assigned by the given value

I am trying to assign a value from a table type variable to a varchar2 type table
CREATE OR REPLACE PACKAGE BODY TEST_SYS IS
TYPE line_table IS TABLE OF VARCHAR2(32767) INDEX BY BINARY_INTEGER;
PROCEDURE test(
val_ OUT VARCHAR2)
IS
temp_val VARCHAR2(4000);
svalues_ line_Table;
BEGIN
svalues_(1) := '! -$FILE_LINE=EXT01;2017-01;2017-
12;JJ01;;4021;;;;;;;;;;;;USD;;;;;;;;1000;1000;; -';
temp_val := svalues_(1);
val_ := temp_val;
END test;
END TEST_SYS
value assignment seems does not happen in the following statement. Does anybody has a clue on this?
temp_val := svalues_(1);
This example only for problem replicate, It may be not logically enhanced one. only to understand the problem.
Provided you have a package test_sys with code :
CREATE OR REPLACE PACKAGE TEST_SYS IS
PROCEDURE test( val_ OUT VARCHAR2);
END TEST_SYS;
and body of the package :
CREATE OR REPLACE PACKAGE BODY TEST_SYS IS
TYPE line_table IS TABLE OF VARCHAR2(32767) INDEX BY BINARY_INTEGER;
PROCEDURE test( val_ OUT VARCHAR2) IS
temp_val varchar2(4000);
svalues_ line_Table;
BEGIN
svalues_(1) := '! -$FILE_LINE=EXT01;2017-01;2017-12;JJ01;;4021;;;;;;;;;;;;USD;;;;;;;;1000;1000;; -';
temp_val := svalues_(1);
val_ := temp_val;
dbms_output.put_line(val_);
END test;
END TEST_SYS;
and call procedure test, you will be able to get the results as in the following :
SQL> set serveroutput on;
SQL> var str varchar2(4000);
SQL> exec test_sys.test(:str);
PL/SQL procedure successfully completed
str
---------
! -$FILE_LINE=EXT01;2017-01;2017-12;JJ01;;4021;;;;;;;;;;;;USD;;;;;;;;1000;1000;; -

Using collection inside dynamic sql

I am trying to pass dbms_sql.number_table from one procedure to another and then using it inside a dynamic plsql block. But the below code throws error as:
Error(6,17): PLS-00306: wrong number or types of arguments in call to '||'
create or replace
procedure proc1( v_in_table_name varchar2,
v_in_column_name varchar2,
v_in dbms_sql.number_table)
as
plsql_block varchar2(4000);
begin
plsql_block:='declare
begin
FORALL INDX IN 1 ..'||v_in.count||' SAVE EXCEPTIONS
UPDATE '||v_in_table_name||'
Set '||v_in_column_name||'=123 WHERE col2='||v_in||'(INDX)||;
end';
execute immediate plsql_block;
end proc1;
You should make two changes:
First(and its case of error) its when you concatinate string with collection.
If you want to send collection into pl/sql block you shoud use the param.
And second you should add ; in the end of dynamic pl\sql:
create or replace
procedure proc1(v_in dbms_sql.number_table)
as
plsql_block varchar2(4000);
begin
plsql_block:='declare
l_collect dbms_sql.number_table := :number_table ;
begin
FORALL INDX IN 1 ..'||v_in.count||' SAVE EXCEPTIONS
UPDATE table_name
Set col1=123 WHERE col2=l_collect(INDX);
end;';
execute immediate plsql_block using v_in;
end proc1;
But after all changes I would like to ask: Are you realy need to use dynamic pl\sql?
There is no need for using a dynamic block. Also i dont think it can work as well. You can use this way;
create or replace
procedure proc1(v_in dbms_sql.number_table)
as
plsql_block varchar2(4000);
l_collect dbms_sql.number_table;
begin
l_collect := v_in;
FORALL INDX IN 1 ..l_collect.count SAVE EXCEPTIONS
UPDATE table_name
Set col1=123
WHERE col2=l_collect(INDX);
commit;
end proc1;
Execution:
SQL> DECLARE
var DBMS_SQL.number_table;
BEGIN
var (1) := 1;
var (2) := 2;
var (3) := 3;
proc1 (var);
END;
/
PL/SQL procedure successfully completed.
EDIT: As per your edit the code becomes like:
create or replace procedure proc1 (v_in_table_name varchar2,
v_in_column_name varchar2,
v_in dbms_sql.number_table)
as
plsql_block varchar2 (4000);
begin
plsql_block := q'[ FORALL INDX IN 1 ..v_in.count SAVE EXCEPTIONS
UPDATE :table_name
Set :col1=123
WHERE col2=v_in(INDX)]';
execute immediate plsql_block using v_in_table_name, v_in_column_name;
commit;
end proc1;

how do I write a stored procedure where an input parameter gives back a result set? [duplicate]

I have created one stored procedure in oracle:
PROCEDURE string_opp(input_string IN varchar2,output_string OUT varchar2)
Now the problem is how to execute this stored procedure and retrieve the output parameter.i've followed in sql developer:
SET SERVEROUTPUT ON
DECLARE
outputString VARCHAR;
BEGIN
EXEC string_opp('input String',:outputString);
END;
When i tried this i didn't get anything, could someone help me?
Just a couple of issues:
SET SERVEROUTPUT ON
DECLARE
outputString VARCHAR(20);
BEGIN
string_opp('input String', outputString);
dbms_output.put_line(outputString);
END;
You can use as the same variable:
SET SERVEROUTPUT ON
DECLARE
outputString VARCHAR(20);
BEGIN
outputString := 'input String';
string_opp(outputString);
dbms_output.put_line(outputString);
END;
Just define your procedure parameter as IN OUT in place of just OUT.
Check this resource:
http://psoug.org/snippet/FUNCTIONS-IN-OUT-parameter_873.htm
Let say:
If you have Store procedure with output parameter:
Create procedure test(name out varchar2(50))
as
begin
name:='testing output parameter';
-- dbms_output.put_line('Output parameter value ' || name );
end;
Now execute the above procedure :
declare
l_name varchar2(50);
begin
test(l_name);
dbms_output.put_line( 'name = ' || l_ename );
end;

retrieve out parameter from stored procedure?

I have created one stored procedure in oracle:
PROCEDURE string_opp(input_string IN varchar2,output_string OUT varchar2)
Now the problem is how to execute this stored procedure and retrieve the output parameter.i've followed in sql developer:
SET SERVEROUTPUT ON
DECLARE
outputString VARCHAR;
BEGIN
EXEC string_opp('input String',:outputString);
END;
When i tried this i didn't get anything, could someone help me?
Just a couple of issues:
SET SERVEROUTPUT ON
DECLARE
outputString VARCHAR(20);
BEGIN
string_opp('input String', outputString);
dbms_output.put_line(outputString);
END;
You can use as the same variable:
SET SERVEROUTPUT ON
DECLARE
outputString VARCHAR(20);
BEGIN
outputString := 'input String';
string_opp(outputString);
dbms_output.put_line(outputString);
END;
Just define your procedure parameter as IN OUT in place of just OUT.
Check this resource:
http://psoug.org/snippet/FUNCTIONS-IN-OUT-parameter_873.htm
Let say:
If you have Store procedure with output parameter:
Create procedure test(name out varchar2(50))
as
begin
name:='testing output parameter';
-- dbms_output.put_line('Output parameter value ' || name );
end;
Now execute the above procedure :
declare
l_name varchar2(50);
begin
test(l_name);
dbms_output.put_line( 'name = ' || l_ename );
end;

Dynamic procedure execution with 'table of varchar and sys_refcursor as an argument

Trying to execute a procedure dynamically with DBMS_SQL that takes 'table of varchar' and sys_refcursor as an argument using the code below:
DECLARE
TYPE CriteriaMap IS TABLE OF VARCHAR (100)
INDEX BY VARCHAR2 (100);
o_cursor SYS_REFCURSOR;
v_cid INTEGER;
v_dummy INTEGER;
v_date_to_run DATE := SYSDATE;
v_sql_execute_proc VARCHAR2 (1024);
v_filter_criteria CriteriaMap;
BEGIN
v_sql_execute_proc :=
'begin MY_PROCEDURE(:v_date_to_run, :filter_criteria, :o_cursor); end;';
v_cid := DBMS_SQL.open_cursor;
DBMS_SQL.parse (v_cid, v_sql_execute_proc, DBMS_SQL.native);
DBMS_SQL.bind_variable (v_cid, 'v_date_to_run', v_date_to_run);
DBMS_SQL.bind_variable (v_cid, 'filter_criteria', v_filter_criteria);
DBMS_SQL.bind_variable (v_cid, 'o_cursor', o_cursor);
v_dummy := DBMS_SQL.execute (v_cid);
DBMS_SQL.close_cursor (v_cid);
END;
as the result the following error is thrown
Error report:
ORA-06550: line 14, column 3:
PLS-00306: wrong number or types of arguments in call to 'BIND_VARIABLE'
Documentation http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_sql.htm says that BIND_VARIABLE takes only a limited number of data types and 'table of varchar' and sys_refcursor are not in the list.
Is there any workaround to pass arguments to a dynamic function which data types are not in the list?
table of varchar is suppoorted through bind_array (though it has to be as per the spec in dbms_sql which is indexed by integer and not varchar2).
can you explain more on why you're using dynamic SQL in this case? as your example does not warrant dynamic SQL as the structure of the call is fixed here.
I know it's old... but if anyone encounters this - it is possible (in 11g, not sure about earlier) to convert the sys ref cursor to a cursor number, bind it, and then transform it to a refcursor after the execute - something like:
declare
vSQL varchar2(1000) := 'declare
v_rc sys_refcursor;
begin
open v_rc for select ''this is a test'' from dual;
:v_cursor_number := dbms_sql.to_cursor_number(v_rc);
end;';
v_rc sys_refcursor;
v_cursor_number NUMBER;
v_cur number;
v_result number;
vFetchValue varchar2(20);
begin
--open the cursor
v_cur := DBMS_SQL.OPEN_CURSOR;
--parse
DBMS_SQL.PARSE(v_cur, vSQL, dbms_sql.native);
--bind the cursor number
DBMS_SQL.BIND_VARIABLE(v_cur, 'v_cursor_number', v_cursor_number);
--execute
v_result := DBMS_SQL.EXECUTE(v_cur);
-- get back the value of the bind cursor number
DBMS_SQL.VARIABLE_VALUE(v_cur,'v_cursor_number', v_cursor_number);
--transform it to a standard sys_refcursor
v_rc := DBMS_SQL.TO_REFCURSOR (v_cursor_number);
--close the cursor
DBMS_SQL.CLOSE_CURSOR(v_cur);
fetch v_rc into vFetchValue;
close v_rc;
dbms_output.put_line(vFetchValue);
end;
/

Resources