How can I use Oracle SQL developer to run stored procedures? - oracle

* EDIT6: * This is what ended up working for me (from accepted answer):
var ret1 number
var tran_cnt number
var msg_cnt number
var rc refcursor
exec :tran_cnt := 0
exec :msg_cnt := 123
exec get_account(Vret_val => :ret1, Vtran_count => :tran_cnt, Vmessage_count => :msg_cnt, Vaccount_id => 1, rc1 => :rc)
print :tran_cnt
print :msg_cnt
print :rc
The SQL Developer makes this super-hard / impossible?. I do not care if the utility is command-line-based; I just want to be able to run and view it quickly. It would be nice if it captured errors well as well. it would be nice to be able to log in gradually(interactively), as well as specifying everything at once (similar to how a typical ftp / sftp cmd-based client works).
My platform is Windows Server 2008 + Cygwin.
EDIT: Perhaps you would know how to script this using Python?
EDIT 2: In MSFT SQL server I can simply type this:
get_user 1;
then highlight it and hit F5, and I get:
login name
NULL Somename
printed to the output window. The Oracle SQL developer does not help with this at all. I am not sure how to pass in a 1, I am not sure how to see the actual rows/records that come back.
EDIT3: When I type just var rc refcursor; and select it and run it, I get this error (GUI):
An error was encountered performing the requested operation:
ORA-00900: invalid SQL statement
00900.00000 - "invalid SQL statement"
* Cause:
* Action:
Vendor code 900Error at Line: 2
EDIT4:
I am trying to run a procedure the definition of which starts like this:
create or replace procedure get_account
(
Vret_val out number,
Vtran_count in out number,
Vmessage_count in out number,
Vaccount_id IN NUMBER
, rc1 in out sys_refcursor
)as
begin
...
I get an error:
Error starting at line 2 in command:
exec :rc := get_account(1)
Error report:
ORA-06550: line 1, column 24:
PLS-00306: wrong number or types of arguments in call to 'GET_ACCOUNT'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
rc
------
I am so close ... please help.
* EDIT 5: *
Script that I am running (functionally the same), the error was always the same:
var ret1 number
var tran_cnt number
var msg_cnt number
var rc refcursor
exec :tran_cnt := 0
exec :msg_cnt := 123
exec get_account(Vret_val => :ret1, Vtran_count => :tran_cnt, Vmessage_count => :msg_cnt, Vaccount_id => 1, rc1 => rc)
Script Output (on F5) (Could be several messages from several runs.):
Error report:
ORA-06550: line 1, column 134:
PLS-00201: identifier 'RC' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
anonymous block completed
anonymous block completed
Error starting at line 7 in command:
exec get_account(Vret_val => :ret1, Vtran_count => :tran_cnt, Vmessage_count => :msg_cnt, Vaccount_id => 1, rc1 => rc)
Error report:
ORA-06550: line 1, column 134:
PLS-00201: identifier 'RC' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
anonymous block completed
anonymous block completed
Error starting at line 7 in command:
exec get_account(Vret_val => :ret1, Vtran_count => :tran_cnt, Vmessage_count => :msg_cnt, Vaccount_id => 1, rc1 => rc)
Error report:
ORA-06550: line 1, column 134:
PLS-00201: identifier 'RC' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Why does it say line 1, column 134? No line stretched that far ...

Not only is there a way to do this, there is more than one way to do this (which I concede is not very Pythonic, but then SQL*Developer is written in Java ).
I have a procedure with this signature: get_maxsal_by_dept( dno number, maxsal out number).
I highlight it in the SQL*Developer Object Navigator, invoke the right-click menu and chose Run. (I could use ctrl+F11.) This spawns a pop-up window with a test harness. (Note: If the stored procedure lives in a package, you'll need to right-click the package, not the icon below the package containing the procedure's name; you will then select the sproc from the package's "Target" list when the test harness appears.) In this example, the test harness will display the following:
DECLARE
DNO NUMBER;
MAXSAL NUMBER;
BEGIN
DNO := NULL;
GET_MAXSAL_BY_DEPT(
DNO => DNO,
MAXSAL => MAXSAL
);
DBMS_OUTPUT.PUT_LINE('MAXSAL = ' || MAXSAL);
END;
I set the variable DNO to 50 and press okay. In the Running - Log pane (bottom right-hand corner unless you've closed/moved/hidden it) I can see the following output:
Connecting to the database apc.
MAXSAL = 4500
Process exited.
Disconnecting from the database apc.
To be fair the runner is less friendly for functions which return a Ref Cursor, like this one: get_emps_by_dept (dno number) return sys_refcursor.
DECLARE
DNO NUMBER;
v_Return sys_refcursor;
BEGIN
DNO := 50;
v_Return := GET_EMPS_BY_DEPT(
DNO => DNO
);
-- Modify the code to output the variable
-- DBMS_OUTPUT.PUT_LINE('v_Return = ' || v_Return);
END;
However, at least it offers the chance to save any changes to file, so we can retain our investment in tweaking the harness...
DECLARE
DNO NUMBER;
v_Return sys_refcursor;
v_rec emp%rowtype;
BEGIN
DNO := 50;
v_Return := GET_EMPS_BY_DEPT(
DNO => DNO
);
loop
fetch v_Return into v_rec;
exit when v_Return%notfound;
DBMS_OUTPUT.PUT_LINE('name = ' || v_rec.ename);
end loop;
END;
The output from the same location:
Connecting to the database apc.
name = TRICHLER
name = VERREYNNE
name = FEUERSTEIN
name = PODER
Process exited.
Disconnecting from the database apc.
Alternatively we can use the old SQLPLus commands in the SQLDeveloper worksheet:
var rc refcursor
exec :rc := get_emps_by_dept(30)
print rc
In that case the output appears in Script Output pane (default location is the tab to the right of the Results tab).
The very earliest versions of the IDE did not support much in the way of SQL*Plus. However, all of the above commands have been supported since 1.2.1. Refer to the matrix in the online documentation for more info.
"When I type just var rc refcursor;
and select it and run it, I get this
error (GUI):"
There is a feature - or a bug - in the way the worksheet interprets SQLPlus commands. It presumes SQLPlus commands are part of a script. So, if we enter a line of SQL*Plus, say var rc refcursor and click Execute Statement (or F9 ) the worksheet hurls ORA-900 because that is not an executable statement i.e. it's not SQL . What we need to do is click Run Script (or F5 ), even for a single line of SQL*Plus.
"I am so close ... please help."
You program is a procedure with a signature of five mandatory parameters. You are getting an error because you are calling it as a function, and with just the one parameter:
exec :rc := get_account(1)
What you need is something like the following. I have used the named notation for clarity.
var ret1 number
var tran_cnt number
var msg_cnt number
var rc refcursor
exec :tran_cnt := 0
exec :msg_cnt := 123
exec get_account (Vret_val => :ret1,
Vtran_count => :tran_cnt,
Vmessage_count => :msg_cnt,
Vaccount_id => 1,
rc1 => :rc )
print tran_count
print rc
That is, you need a variable for each OUT or IN OUT parameter. IN parameters can be passed as literals. The first two EXEC statements assign values to a couple of the IN OUT parameters. The third EXEC calls the procedure. Procedures don't return a value (unlike functions) so we don't use an assignment syntax. Lastly this script displays the value of a couple of the variables mapped to OUT parameters.

I am not sure how to see the actual
rows/records that come back.
Stored procedures do not return records. They may have a cursor as an output parameter, which is a pointer to a select statement. But it requires additional action to actually bring back rows from that cursor.
In SQL Developer, you can execute a procedure that returns a ref cursor as follows
var rc refcursor
exec proc_name(:rc)
After that, if you execute the following, it will show the results from the cursor:
print rc

My recommendation is TORA

Have you heard of "SQuirreL SQL Client"?
http://squirrel-sql.sourceforge.net/

There are two possibilities, both from Quest Software, TOAD & SQL Navigator:
Here is the TOAD Freeware download: http://www.toadworld.com/Downloads/FreewareandTrials/ToadforOracleFreeware/tabid/558/Default.aspx
And the SQL Navigator (trial version): http://www.quest.com/sql-navigator/software-downloads.aspx

Related

How to avoid this in PLSQL

I'm trying to create a function that looks like this
CREATE OR REPLACE FUNCTION get_sal
(dep_id IN departments.department_id%TYPE)
RETURN NUMBER IS
v_sal employees.salary%TYPE;
BEGIN
SELECT AVG(salary) INTO v_sal FROM Employees
WHERE department_id = dep_id;
RETURN v_sal;
END;
And I get an error that says
Error starting at line : 5 in command -
BEGIN
SELECT AVG(salary) INTO v_sal FROM Employees
WHERE department_id = dep_id;
RETURN v_sal;
END;
Error report -
ORA-06550: line 3, column 27:
PL/SQL: ORA-00904: "DEP_ID": invalid identifier
ORA-06550: line 2, column 5:
PL/SQL: SQL Statement ignored
ORA-06550: line 4, column 5:
PLS-00372: In a procedure, RETURN statement cannot contain an expression
ORA-06550: line 4, column 5:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
I got an example function from Oracle to see if it works but the same error appears.
There's nothing wrong with the function:
SQL> CREATE OR REPLACE FUNCTION get_sal (dep_id IN departments.department_id%TYPE)
2 RETURN NUMBER
3 IS
4 v_sal employees.salary%TYPE;
5 BEGIN
6 SELECT AVG (salary)
7 INTO v_sal
8 FROM Employees
9 WHERE department_id = dep_id;
10
11 RETURN v_sal;
12 END;
13 /
Function created.
SQL> select get_sal(10) from dual;
GET_SAL(10)
-----------
SQL>
as long as schema you're connected to contains DEPARTMENTS and EMPLOYEES tables with columns mentioned in that code. If you do not, then yes - expect errors.
As it seems you are using Sql Developer 20.4.0 as your SQL client, i guess the problem comes from the way you're compiling your SQL statement within this SQL client.
With SQL Developer, there is two ways to compile a SQL statement/execute a query. Selecting it in the editor and then click the green play button on the left as shown in the image below. The second way is to have only your statements in the editor and use the execute script button which is the second button to the right of the green play button. This one will execute all the statements in the editor.
I guess your error come from the use of the green play button while your cursor in the editor is on the statement but the statement is not fully selected or partially selected.
You can make SQL Developer complies with the behavior of Toad or have a custom behavior in this way in the SQL Developer options.

Get the first value from Oracle cursor - Calling From Java Code

I have a oracle cursor which I have created to facilitate concurrency. This is my cursor.
create or replace FUNCTION get_unlocked_records RETURN table_to_test%ROWTYPE IS
CURSOR c IS SELECT * FROM table_to_test where status_code = 5 FOR UPDATE SKIP LOCKED;
record_to_get table_to_test%ROWTYPE;
BEGIN
OPEN c;
FETCH c INTO record_to_get;
CLOSE c;
RETURN record_to_get;
END;
When I do the testing in 2 separate sql sessions using these commands,it gives the following errors.
declare
record_to_gets table_to_test%ROWTYPE;
begin
exec :record_to_gets := get_unlocked_records;
dbms_output.put_line(record_to_gets);
end;
Error
Error starting at line : 32 in command -
declare
record_to_gets table_to_test%ROWTYPE;
begin
exec :record_to_gets := get_unlocked_records;
dbms_output.put_line(record_to_gets);
end;
Error report -
ORA-06550: line 4, column 7:
PLS-00103: Encountered the symbol "" when expecting one of the following:
:= . ( # % ;
The symbol ";" was substituted for "" to continue.
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
What is the error that I am doing here ?
Since my ultimate goal is to call the function and get the result in java, how to call this function to get the first record in java ?
Thanks in advance.
EXEC[UTE] is a SQL*Plus command and prepending variable with a colon is done in SQL*Plus, but in PL/SQL EXECUTE IMMEDIATE might be used whereas that's not needed in your case, only using such an assignment without prepending the local variable is enough :
DECLARE
record_to_gets table_to_test%ROWTYPE;
BEGIN
record_to_gets := get_unlocked_records;
DBMS_OUTPUT.PUT_LINE(record_to_gets.col1);
DBMS_OUTPUT.PUT_LINE(record_to_gets.col2)
END;
/

Stored procedure expects parameter when no IN parameters are defined

I have this very simple stored procedure in Oracle that executes a sequence and gives the next sequence number as output.
create or replace PROCEDURE NEXT_NUMBER
(SEQUENCE_OUT OUT NUMBER)
IS
BEGIN
EXECUTE IMMEDIATE 'SELECT TEST_SEQUENCE.NEXTVAL FROM DUAL' INTO sequence_out;
END;
As you can see, there are no IN parameters to this procedure so I'm puzzled when I execute this procedure like this: execute CRS_NEXT_CRC_NUMBER;
and I get the following error:
Error starting at line : 1 in command -
execute NEXT_NUMBER
Error report -
ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'CRS_NEXT_CRC_NUMBER'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Any idea why this could be happening? I can call the NEXTVAL function on the SEQUENCE outside of the procedure without a problem.
create or replace PROCEDURE NEXT_NUMBER
(SEQUENCE_OUT OUT NUMBER)
IS
BEGIN
SELECT TEST_SEQUENCE.NEXTVAL INTO sequence_out FROM DUAL;
-- or simply (in newer Oracle releases)
sequence_out := TEST_SEQUENCE.NEXTVAL;
END;
In SQLPLUS:
> var ID NUMBER
> exec NEXT_NUMBER(:ID);
> print ID
PLS-00306: wrong number or types of arguments in call to 'CRS_NEXT_CRC_NUMBER'
You have not declared the OUT parameter and the program expects an argument, i.e. the OUT parameter SEQUENCE_OUT.
You could execute the procedure with the OUT parameter in two ways.
SQL*Plus variable
Anonymous block
In SQL*Plus:
var SEQUENCE_OUT number
exec next_number(:SEQUENCE_OUT);
print SEQUENCE_OUT
Anonymous block:
SET SERVEROUTPUT ON
DECLARE
SEQUENCE_OUT NUMBER;
BEGIN
next_number(SEQUENCE_OUT);
DBMS_OUTPUT.PUT_LINE(SEQUENCE_OUT);
END;
/
You done almost correct. You need to call method like
execute NEXT_NUMBER(:val);
You don't set out parameter, which will take out value.

PL/SQL : i have a function but there is an error : "in a procedure,RETURN can not contain an expression"

Here is my code:
CREATE OR REPLACE FUNCTION customer_city_function(city_in IN VARCHAR2)
RETURN NUMBER
AS
number_cus NUMBER := 0;
CURSOR cus_cur IS
SELECT COUNT(*)
FROM customer
WHERE customer_city = city_in;
BEGIN
IF city_in IS NOT NULL THEN
OPEN cus_cur;
FETCH cus_cur INTO number_cus;
CLOSE cus_cur;
END IF;
RETURN number_cus;
END;
/
and here is warnings:
Error starting at line : 1 in command -
CREATE OR REPLACE FUNCTION customer_city_function(city_in IN VARCHAR2)
RETURN NUMBER
AS
number_cus NUMBER := 0
Error report -
SQL Command: functıon CUSTOMER_CITY_FUNCTION
Failed: Warning: executing is completed with a warning
Error starting at line : 5 in command -
CURSOR cur_cur IS
Error report -
Unknown Command
Error starting at line : 6 in command -
SELECT COUNT(*)
FROM costumer
WHERE customer_city=city_in
Error at Command Line : 8 Column : 25
Error report -
SQL Error: ORA-00904: "CITY_IN": undefined variable
00904. 00000 - "%s: invalid identifier"
*Cause:
*Action:
Error starting at line : 9 in command -
BEGIN
IF city_in IS NOT NULL
THEN
OPEN cus_cur;
FETCH cus_cur INTO number_cus;
CLOSE cus_cur;
END IF;
RETURN (number_cus);
END;
Error report -
ORA-06550: row 2, column 6:
PLS-00201: 'CITY_IN' variable should been defined
ORA-06550: row 2, column 3:
PL/SQL: Statement ignored
ORA-06550: row 8, column 1:
PLS-00372: in a procedure, RETURN can not contain an expression
ORA-06550: row 8, column 1:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Where is my mistake? I can't find it, it doesn't make any sense.
(I translated this warning message from my language. I hope I did it right.)
I have just tried it in Command Window and it works. Why doensn't it work in Oracle SQL Developer sql worksheet?
There is nothing wrong with your posted code. The issue might be with your client or the way you are compiling the code.
As you have mentioned PL/SQL Developer in the tags, it might be possible that you have some extra characters in the SQL Worksheet and you are compiling the function as a script, thus the compiler finds it erroneous.
Here is a demo in SQL*Plus, and there is no error:
SQL> CREATE OR REPLACE FUNCTION customer_city_function(i_deptno IN number)
2 RETURN NUMBER
3 AS
4 number_cus NUMBER := 0;
5 CURSOR cus_cur IS
6 SELECT COUNT(*)
7 FROM emp
8 WHERE deptno=i_deptno;
9 BEGIN
10 IF i_deptno IS NOT NULL
11 THEN
12 OPEN cus_cur;
13 FETCH cus_cur INTO number_cus;
14 CLOSE cus_cur;
15 END IF;
16 RETURN number_cus;
17 END;
18 /
Function created.
SQL> sho err
No errors.
SQL> SELECT customer_city_function(10) FROM DUAL;
CUSTOMER_CITY_FUNCTION(10)
--------------------------
3
SQL>
The only difference in my code is that I have used EMP table instead of CUSTOMERS table and the input parameter is DEPTNO instead of CITY_IN. Rest everything is same and function compiles and executes without any errors.

Compilation errors on stored procedure

I am typically a SQL Server developer however am now working with a system that uses Oracle. I have created a new procedure and am getting a runtime error. Here is the procedure:
CREATE OR REPLACE PROCEDURE CHK_LASTAPPTIME
(
LASTAPPTIME OUT VARCHAR2
)
IS
v_appappid varchar2(20) null;
v_lastapptime number null;
BEGIN
select max(APPID) into v_appappid from applicationtable;
select trunc(v_lastapptime = (((sysdate - capturedate) * 24)) * 60) from applicationtable where APPID = v_appappid;
LASTAPPTIME := to_char(v_lastapptime);
END CHK_LASTAPPTIME;
Here is the error that I am getting:
SQL> var x varchar2;
SQL> exec CHK_LASTAPPTIME(:x);
BEGIN CHK_LASTAPPTIME(:x); END;
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at "CAPDEV.CHK_LASTAPPTIME", line 19
ORA-06512: at line 1
Your proecedure doesn't have 19 lines, so the message is odd, or you've shown different code to what you're actually running. Since what you've shown doesn't compile I'm assuming you've tried to cut it down for the question, and I'll also assume your actual procedure is valid and does what you want.
The problem is in your run-time variable declaration. You haven't specified a size for x, so it uses a default. On my DB, in SQL*Plus that seems to allow three characters but errors with four or more:
var x varchar2;
exec :x := 'a';
PL/SQL procedure successfully completed.
exec :x := 'ab';
PL/SQL procedure successfully completed.
exec :x := 'abc';
PL/SQL procedure successfully completed.
exec :x := 'abcd';
BEGIN :x := 'abcd'; END;
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 1
The limit might be related to your character set, perhaps. SQL Developer allows more by default.
Anyway, specify the size for your variable:
var x varchar2(30);
exec CHK_LASTAPPTIME(:x);
You seem to be generating a number in your procedure, and then returning that as a string. Using the same data type would make this a bit simpler.

Resources