Calling Procedure in 1 line - sql

I have a question about calling a procedure in Oracle.
This is what I have and this works fine in SQLPlus.
VARIABLE resultSet REFCURSOR;
BEGIN
CALL_TEST('10DD', :resultSet);
END;
/
But, the code below doesn't work because it gives me the explanation of the variable instead of saying "PL/SQL procedure successfully completed."
VARIABLE resultSet REFCURSOR; BEGIN HUGHES_ARIAL.DUNNING_TEST('1D10', :resultSet); END; /
The issue is I need to press enter after every ; (semicolon). Is there a way to make my statement above to work with just 1 line without having to press enter?
I am using an email campaign enterprise software, but it doesn't allow me to do what I can do in SQLPlus.

All SQL*Plus commands should be within one line. When clubbing different commands, it has to be in multiple lines.
Example:
SQL> variable test NUMBER;set linesize 0;
Usage: VAR[IABLE] [ <variable> [ NUMBER | CHAR | CHAR (n [CHAR|BYTE]) |
VARCHAR2 (n [CHAR|BYTE]) | NCHAR | NCHAR (n) |
NVARCHAR2 (n) | CLOB | NCLOB | REFCURSOR |
BINARY_FLOAT | BINARY_DOUBLE ] ]
Your Procedure can be invoked this way, using EXEC.
VARIABLE resultSet REFCURSOR;
EXEC CALL_TEST('10DD', :resultSet);
OR
VARIABLE resultSet REFCURSOR;
BEGIN CALL_TEST('10DD', :resultSet); END;
/
Your entire PL/SQL block may be in one line, where-as when attempted to execute, you have to explicitly specify the '/' as a new line!
If you are concern in running in multiple lines,
Put it in a file and run as Script.
SQL> !cat my_script.sql
VARIABLE resultSet REFCURSOR;
BEGIN
CALL_TEST('10DD', :resultSet);
END;
/
SQL> start my_script.sql

Related

how to pass in array in procedure call in oracle

I have a procedure that takes in an array in postgres, this syntax works:
SELECT * from myMethod(array['test','test'], array[''], 554, 73430, 322234, 'shazam');
the array keyword is what I am referring to. this works in postgres but I cannot find the documentation to understand how this work in oracle. how do i pass in arrays to function call?
the error when running the above is:
ORA-00933: SQL command not properly ended
00933. 00000 - "SQL command not properly ended"
*Cause:
*Action:
Error at Line: 4 Column: 38
If you have the type:
CREATE TYPE array IS TABLE OF VARCHAR2(200);
and create your function:
CREATE FUNCTION myMethod(
p_words IN array,
p_suffixes IN array,
p_value1 IN INT,
p_value2 IN INT,
p_value3 IN INT,
p_prefix IN VARCHAR2
) RETURN array PIPELINED DETERMINISTIC
IS
value VARCHAR2(200);
BEGIN
FOR i IN 1 .. p_words.COUNT LOOP
value := p_prefix || p_words(i);
FOR j IN 1 .. p_suffixes.COUNT LOOP
value := value || p_suffixes(j);
END LOOP;
PIPE ROW ( value );
END LOOP;
END;
/
Then you can do:
SELECT * from myMethod(array('test1','test2'), array('ab','cd'), 554, 73430, 322234, 'shazam');
In earlier Oracle versions, you may need to use:
SELECT * from TABLE( myMethod(array('test1','test2'), array('ab','cd'), 554, 73430, 322234, 'shazam') );
and it outputs:
| COLUMN_VALUE |
| :-------------- |
| shazamtest1abcd |
| shazamtest2abcd |
db<>fiddle here
Here's an example; I'm using built-in sys.odcivarchar2list type. You'd use your own (if this doesn't suit your needs).
SQL> create or replace procedure p_arr (par_array in sys.odcivarchar2list) is
2 begin
3 dbms_output.put_line(par_array(1));
4 end;
5 /
Procedure created.
Testing:
SQL> set serveroutput on
SQL> exec p_arr(sys.odcivarchar2list('A', 'B'));
A
PL/SQL procedure successfully completed.
SQL>

Why does invoking procedure that uses REGEX_SUBSTR through PLSQL code block return an extra '¬' char?

Editing in PLSQL.
I've got the following procedure:
SET SERVEROUTPUT ON
CREATE OR REPLACE PROCEDURE StringTest(StringToTest IN varchar2)
AS
result varchar2(100);
BEGIN
result := REGEXP_SUBSTR(StringToTest, '[a-zA-Z0-9]{1,}\/?\s?\w*(\/\d{4})?',1,1);
DBMS_OUTPUT.PUT_LINE('Result is ' || result);
END;
/
The purpose of this procedure is to take in a string, match it with the regex, and then return the first match in the string. I understand for this example the regex is more complicated than it needs to be, but that is because I have truncated the code to its simplest form. The actual code is much more complex, and therefore the regex looks more complex than it needs to for this example.
When I invoke the procedure through a PLSQL code block such as
SET SERVEROUTPUT ON
DECLARE
String1 varchar2(100);
BEGIN
String1 := '(‘Hello’)';
StringTest(String1);
END;
/
I get the following:
Result is Hello¬
When I invoke the procedure through an EXEC statement such as
EXEC StringTest('(‘Hello’)');
I get the following
Result is Hello
The second result is what I expect in both cases. My question is, why does invoking the same exact procedure through a PLSQL code block add the extra ¬ character to the output?

Why no output when PLSQL Anonymous block completes? [duplicate]

This question already has answers here:
Printing the value of a variable in SQL Developer
(9 answers)
Closed 4 years ago.
I'm just getting into PL/SQL, and I tried to run the following code, and I am getting anonymous block completed, but I think I should be getting Testing output. Does any know what I am doing wrong?
DECLARE
message varchar2(20) := 'Testing output';
BEGIN
dbms_output.put_line(message);
END;
/
Viewing the DBMS_OUTPUT depends on the program.
SQL*Plus and Oracle SQL Developer
Run SET SERVEROUTPUT ON; first. This is all that's necessary in SQL*Plus or recent versions of Oracle SQL Developer.
SET SERVEROUTPUT ON;
begin
dbms_output.put_line('Testing output');
end;
/
PL/SQL Developer
Output is automatically detected and displayed in the "Output" tab.
Yes, in Oracle SQL Developer put the statement:
SET SERVEROUTPUT ON;
just before your DECLARE keyword and this should work.
I couldn't find View -> DBMS Output and I'm using version 1.5.5.
Yes. There is way to see output in SQL Developer.
Click ->View->Dbms Output and then click + symbol on Dbms output window. now you can run the procedure and can see output.
`The following statement will give the possible solution try this out
SET SERVEROUTPUT ON;
Then Run this code will get the following output
declare
a integer :=10;
b integer :=20;
c integer;
f real;
begin
c := a+b;
dbms_output.put_line('value of c: ' || c);
f := 70.0/3.0;
dbms_output.put_line('value of f: ' || f);
end;
/
The code will give the following output
value of c: 30
value of f: 23.3333333333333333333333333333333333333
PL/SQL procedure successfully completed.
Yes, this is correct. You need to use before this block:
SET SERVEROUTPUT ON
Then, message get displayed on window.
Else we can check in SQL Developer select "View" -> "DBMS Output".
and in PLSQL developer under the OutPut tab we can check message.
If you are getting "anonymous block completed" while executing the procedure by typing "EXECUTE ;" then run the below command & again execute the procedure.
command is
SET SERVEROUTPUT ON;
**SET SERVEROUTPUT ON;**
DECLARE
a INTEGER :=10;
b INTEGER :=20;
c float ;
d real ;
BEGIN
c :=a+b;
dbms_output.put_line('the value of C is :'|| c);
d := 70.0/3.3;
dbms_output.put_line('the value of d is:'|| d);
END;
This will give you the output
the value of C is: 30
the value of d is: 21.21212121212121212121212121212121212121

Inconsistent behaviour when executing a function from within Oracle SQL*Plus?

I am new to Oracle and SQL and am trying to execute a simple test function from within SQL*Plus. My function is called tf (for Test Function) and it is defined in a file called tf.sql as follows ;
create or replace
function
tf
(
arg1 in varchar2
)
return number
as
return_value number;
begin
return_value := 0;
dbms_output.put_line('Argument 1 = ' || arg1);
return return_value;
end;
/
I am able to successfully load this function into Oracle using the following command ;
SQL> start ./tf.sql
As a result of executing this command, SQL*Plus simply states ;
Function created.
When I then execute the following command from the SQL*Plus command prompt (after I have invoked set serveroutput on) ;
SQL> exec dbms_output.put_line(SYSTEM.TF('Hello'));
I get the following output ;
Argument = Hello
0
PL/SQL procedure successfully completed.
Now, if I attempt to execute my function directly from the SQL*Plus command prompt, using the following command ;
SQL> exec SYSTEM.TF('Hello');
then I get presented with the following error message from SQL*Plus ;
BEGIN SYSTEM.TF('Hello'); END;
*
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00221: 'TF' is not a procedure or is undefined
ORA-06550: ;ine 1, column 7
PL/SQL: Statement ignored
Is anyone able to shed any light on this for me? I can't work out why my function appears to execute successfully in the first case, but not in the second case.
If I execute the following command from the SQL*Plus command prompt ;
SQL> select * from user_objects where object_name = 'TF';
then I get the following results returned ;
OBJECT_NAME
-----------
TF
SUBOBJECT_NAME
--------------
OBJECT_ID
---------
74475
DATA_OBJECT_ID
--------------
OBJECT_TYPE
-----------
FUNCTION
CREATED
-------
05-FEB-12
LAST_DDL_
---------
05-FEB-12
TIMESTAMP
---------
2012-02-05:02:11:15
STATUS
------
VALID
T
-
N
G
-
N
S
-
N
EDITION_NAME
------------
1
Any help on this would be immensely appreciated.
Thanks in advance.
Craig
exec does not work with functions because it does not know what to do with the return value. This is similar to a regular PL/SQL statement; if you call a function you must assign the return value to something.
If you want to use a function in SQL*Plus, you should use SQL instead:
select tf('asdf') from dual;
Also, you should never create objects in SYSTEM. This can cause some really weird problems.
Following on from #jonearles answer,which highlights the difference between a function and a procedure from SQL*Plus' perspective, and #MS Stp's comment, one way to run it is:
variable rc number;
exec :rc := tf('Hello');
Argument = Hello
PL/SQL procedure successfully completed.
To see the return code you can then do:
print rc
0
exec is really just shorthand for an anonymous PL/SQL block, as you can see from the error message you got. variable lets you declare a bind variable at SQL*Plus level, rather than in the block. You can also declare the argument as bind variable, and set it with a separate exec call:
variable rc number;
variable arg varchar2(5);
exec :arg := 'Hello';
exec :rc := tf(:arg);
I often use this construct for testing an existing procedure call, e.g. something copied from Pro*C code, without having to replace the variables in that call with fixed values. It can make it easier to call repeatedly with different arguments, and you can reuse variables in several calls - so you could pass :rc to another function later.

Oracle SQL Developer - Missing IN or OUT parameter at index:: 1

I am having trouble testing this simple stored procedure in Oracle Sql Developer. The stored procedure does a simple select and returns a cursor.
create or replace
PROCEDURE GET_PROJECT_DRF_HISTORY
( projectId IN NUMBER,
resultset_out OUT sys_refcursor
) AS
BEGIN
OPEN resultset_out for
SELECT * from GLIDE_HISTORY
where GLIDE_HISTORY.PRJ_ID = projectId;
/* DBMS_OUTPUT.PUT_LINE(resultset_out);*/
END GET_PROJECT_DRF_HISTORY;
To test this procedure, I used the below script:
variable results sys_refcursor;
exec get_project_drf_history(3345, :results);
print :results;
Being new to both oracle and the Sql Developer tool, I am struggling to understand what is the mistake here. I cannot check this in Sql*Plus because I dont have the password to do so. I am using Oracle Sql Developer 1.1.2.25 and Oracle 10g.
Can anybody help me out please? Thank you in advance.
Sammy,
The variable declaration should be refcursor instead of sys_refcursor.
Also when you print the results, you are printing the variable itself, so there is no need for a : (which is used to indicateit is a bind variable).
I was able to run the following script sucessfully in SQL Developer (and of course sql plus.)
For SQL Developer, run it as a script using F5.
--Creating Procedure
create or replace procedure test_ref(
i_limit number,
o_results out sys_refcursor
) is
begin
open o_results for
'select object_name
from all_objects
where rownum < ' || i_limit;
end;
/
And then the script that calls this procedure. (excute as a script using F5).
var c1 refcursor;
exec test_ref(10,:c1);
print c1;
here is a working example, declare the refcursor then assign the value by calling you proc in an anonymous block.
then you print it
var x REFCURSOR ;
declare
/*a no cleanup procedure*/
procedure GetMeMyRefCursor(outter out nocopy sys_refcursor)
as
begin
open outter for
select level
from dual
connect by level <= 5;
end GetMeMyRefCursor;
begin
GetMeMyRefCursor(:x);
/*note you pass in the refcursor you created via the :X*/
end ;
/
print x;
/*now print it*/
/*LEVEL
----------------------
1
2
3
4
5*/
based on comment:
now using your comment, you are having an issue with IN/OUT params and not with the print (didn't read the title just the question and the other response)
this works: (based on your code)
create or replace
PROCEDURE GET_PROJECT_DRF_HISTORY
( projectId IN NUMBER,
resultset_out OUT sys_refcursor
) AS
BEGIN
OPEN resultset_out for
SELECT level from dual connect by level <= projectId;
/* DBMS_OUTPUT.PUT_LINE(resultset_out);*/
END GET_PROJECT_DRF_HISTORY;
/
var results REFCURSOR;
--this needs to be REFCURSOR (at least in 10g and 11i)
exec GET_PROJECT_DRF_HISTORY(5, :results);
print results;
/
You can also debug packages and procedures directly from SQL Developer (this can be a real life saver)
if you want to debug in SQL Developer it is really easy:
in the connections->your schema here-->procedures -> GET_PROJECT_DRF_HISTORY right click and 'Compile for debug'. Then in the procedure place a break point in it, then right click and 'debug' it (this will create an anonymous block -- see below -- where you can put in your values and such)
DECLARE
PROJECTID NUMBER;
RESULTSET_OUT sys_refcursor;
BEGIN
PROJECTID := NULL;
GET_PROJECT_DRF_HISTORY(
PROJECTID => PROJECTID,
RESULTSET_OUT => RESULTSET_OUT
);
-- Modify the code to output the variable
-- DBMS_OUTPUT.PUT_LINE('RESULTSET_OUT = ' || RESULTSET_OUT);
END;
(http://www.oracle.com/technetwork/developer-tools/sql-developer/sqldeveloperwhitepaper-v151-130908.pdf page 11)
otherwise, the error doesn't look as it should appear if you are doing this all from Developer.
But what I really think is happening is your VAR is incorrect and thus it doesn't exists!
variable results sys_refcursor;
Usage: VAR[IABLE] [ <variable> [ NUMBER | CHAR | CHAR (n [CHAR|BYTE]) |
VARCHAR2 (n [CHAR|BYTE]) | NCHAR | NCHAR (n) |
NVARCHAR2 (n) | CLOB | NCLOB | REFCURSOR |
BINARY_FLOAT | BINARY_DOUBLE ] ]
so, going from my initial example "var x REFCURSOR ;" should work
I recommend asking your administrator to upgrade your SQL Developer version. Yours is significantly outdated and you may be running into some obscure bugs. (I did when I tried to use version 1) You should be on 2.1 by now.