PLSQL Problem for checking if cursor ISOPEN - oracle

What I am trying to achieve is to check if the cursor is open or not as a safety precaution but I always get this error. Any sort of help would be much appreciated.
LINE/COL ERROR
-------- -----------------------------------------------------------------
29/5 PL/SQL: SQL Statement ignored
29/5 PLS-00306: wrong number or types of arguments in call to
'WROTE_CUR'
CREATE OR REPLACE PROCEDURE print_publication (p_name CHAR) AS
CURSOR wrote_cur (v_AID NUMBER) IS
SELECT AID,PUBID FROM wrote WHERE AID = v_AID;
v_wrote_rec wrote_cur%ROWTYPE;
BEGIN
IF NOT wrote_cur%ISOPEN THEN
OPEN wrote_cur;
END IF;
CLOSE wrote_cur;
END;
/

You declared cursor with an input Argument.
CURSOR wrote_cur (v_AID NUMBER) IS --<-- Cursor is expecting argument at runtime
While in the Begin block you are not passing any argument to the cursor.
OPEN wrote_cur; --<-- Here..
pass the argument like:
OPEN wrote_cur(1);

Mistake : Forgot to pass an argument
IF NOT wrote_cur%ISOPEN THEN
OPEN wrote_cur (v_author_ID);
END IF;

Related

Oracle begin expected got create

I'm writing a PL/SQL program, I've created a procedure and the syntax is correct.
Running this on DataGrip.
`
declare
create or replace procedure salutation(x OUT number) is begin
x:= x*10;
end salutation;
begin
SYS.DBMS_OUTPUT.PUT_LINE('hello');
end;
`
I get error messages when I execute the code:
BEGIN expected, got 'create'.
[2022-12-04 23:58:09] [65000][6550]
[2022-12-04 23:58:09] ORA-06550: line 1, column 7:
[2022-12-04 23:58:09] PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
[2022-12-04 23:58:09] begin function pragma procedure subtype type
[2022-12-04 23:58:09] current cursor delete
[2022-12-04 23:58:09] exists prior
I don't think there's a problem with the syntax.
Also why does the DataGrip not allow DBMS_OUTPUT.PUT_LINE without the SYS. ? even though I've enabled the DBMSOUTPUT.
You can't have static DDL statements (like create procedure) within PL/SQL (you'd need to use dynamic SQL, but it's very rarely necessary anyway).
But if you're trying to declare a local procedure within your anonymous block - not create a permanent, stored procedure, then you don't need the create part:
declare
y number := 42;
procedure salutation(x IN OUT number) is begin
x:= x*10;
end salutation;
begin
SYS.DBMS_OUTPUT.PUT_LINE('hello');
-- call salutation here if you want...
salutation(y);
dbms_output.put_line(to_char(y));
end;
/
1 rows affected
dbms_output:
hello
420
fiddle
Note that I changed the argument to IN OUT - otherwise it would always be reset to null.
If you want to create a permanent stored procedure then do that separately, before you try to run your anonymous block:
create or replace procedure salutation(x IN OUT number) is begin
x:= x*10;
end salutation;
/
declare
y number := 42;
begin
SYS.DBMS_OUTPUT.PUT_LINE('hello');
-- call salutation here if you want...
salutation(y);
dbms_output.put_line(to_char(y));
end;
/
1 rows affected
dbms_output:
hello
420
fiddle
Also why does the DataGrip not allow DBMS_OUTPUT.PUT_LINE without the SYS. ?
That suggests your database is missing a public synonym for the package; not a DataGrip thing, you'd see the same behaviour using any client. You'd need to ask your DBA why it's missing and whether it can be reinstated. (I haven't included the schema prefix in the extra calls I added, but if those don't work for you then you'll need to add it.)

How to write an Oracle procedure with a select statement (Specifically on SQL Developer)?

I want to create a simple Oracle Stored procedure on SQL Developer that will return some records on a simple select query. I do not want to pass in any parameter, but I just want the Records to be returned back from the procedure into a result set -> a suitable variable.
I have been trying to use the following syntax :
create or replace PROCEDURE Getmarketdetails2(data OUT varchar2)
IS
BEGIN
SELECT *
into data
from dual;
END Getmarketdetails2;
But it gives me an error while I try to execute with the following exec statement -->
Declare a Varchar2;
exec Getmarketdetails2(a);
Error: PLS-00103: Encountered the symbol "end-of-file" when expecting "something else".
Cause: Usually a PL/SQL compilation error.
Appreciate if anyone can help me out of this long pending situation! I have tried enough to find a basic guide to create a simple Oracle stored procedure and execute it in SQL Developer, but none of them answer to the point!!
You want:
DECLARE
a VARCHAR2(4000); -- Give it a size
BEGIN -- Begin the anonymous PL/SQL block
Getmarketdetails2(a); -- Call the procedure
DBMS_OUTPUT.PUT_LINE( a ); -- Output the value
END; -- End the anonymous PL/SQL block
/ -- End the PL/SQL statement
or:
VARIABLE a VARCHAR2(4000); -- Create a bind variable
EXEC Getmarketdetails2(:a); -- Execute the procedure using the bind variable
PRINT a -- Print the bind variable
Assuming an up-to-date Oracle version, you can use dbms_sql.return_result()
create or replace PROCEDURE Getmarketdetails2
IS
c1 SYS_REFCURSOR;
BEGIN
OPEN c1 FOR
SELECT *
from dual;
DBMS_SQL.RETURN_RESULT(c1);
END Getmarketdetails2;
/
Then simply run
exec Getmarketdetails2
The only drawback is that SQL Developer only displays the result as text, not as a proper result grid.
This is how I return a cursor in Oracle
PROCEDURE GetAllData (P_CURSOR OUT SYS_REFCURSOR)
IS
BEGIN
OPEN P_CURSOR FOR
SELECT *
FROM TABLE ;
END GetAllData ;
Declare a Varchar2;
exec Getmarketdetails2(a);
Your procedure is ok;
Instead of above query, use below query to run sp:
Declare
a Varchar2(10);
Begin
Getmarketdetails2(a);
End;

How to declare / assign a variable to a cursor type in PL/SQL procedure

I have two cursors declared in a stored procedure (inside a package).
procedure RECONCILE_CC_TRX (p_to_date in date,
p_nz_flag in varchar2,
p_Reconcile_Header_ID out NUMBER
) is
CURSOR LOADED_TRXS_AU IS
SELECT
CC_REC_LOAD_TRX_ID,
CC_REC_LOAD_HEADER_ID,
....
CURSOR LOADED_TRXS_NZ IS
SELECT
CC_REC_LOAD_TRX_ID,
CC_REC_LOAD_HEADER_ID,
The only difference between the two cursors is the where clause.
What I want to do, is open one of those cursors based on the p_nz_flag passed in above. ie:
IF NVL(p_nz_flag, 'F') = 'F' THEN
v_load_trx_cursor := LOADED_TRXS_AU;
ELSE
v_load_trx_cursor := LOADED_TRXS_NZ;
END IF;
FOR bitem IN v_load_trx_cursor LOOP
...
My initial thinking was to declare a variable and assign it the appropriate cursor, however, I can't get the procedure to compile with this. eg, I have tried:
v_load_trx_cursor sys_refcursor;
but I get a compilation error when assigning v_load_trx_cursor of "PLS-00382: Expression is of wrong type". If I change my declaration to:
v_load_trx_cursor cursor;
I get compilation error at the declaration point stating "PLS-00201: Identifier 'Cursor' must be declared.
Is it possible to do what I want to do? At the end of the day, I just want to iterate the appropriate cursor based on the p_nz_flag parameter passed in.
Thanks
It looks like you want to use only one cursor in your code, based on the value of p_nz_flag
In this case, believe it will be better to make the where clause dynamically in your code and then use refcursor to return the data of the query.
Something like given in Example 7-4 on this link Dynamic Query with Refcursor
Hope it Helps
Vishad
Hi if your whole work for doing this procedure is just to populate the appropriate cursor i think this code may help you.
CREATE OR REPLACE PROCEDURE av_nst_cursor(
flag_in IN VARCHAR2,
av_cur OUT sys_refcursor)
AS
BEGIN
IF flag_in = 'Y' THEN
OPEN av_cur FOR SELECT Query;
ELSE
OPEN av_cur FOR SELECT query;
END IF;
END;

SQLPLUS object system. is invalid

I'm stuck with some simple procedure and I can't figure out why.
This is my code, which I'm running in sqlplus:
CREATE OR REPLACE PROCEDURE NormalizeName(fullname IN NVARCHAR2)
IS
BEGIN
SELECT TRIM(fullname) INTO fullname FROM DUAL;
DBMS_OUTPUT.PUT_LINE(fullname);
END NormalizeName;
/
BEGIN
NormalizeName('Alice Wonderland ');
END;
/
When I run it, I get the error:
Warning: Procedure created with compilation errors.
NormalizeName('Alice Wonderland ');
*
ERROR at line 2:
ORA-06550: line 2, column 2:
PLS-00905: object SYSTEM.NORMALIZENAME is invalid
ORA-06550: line 2, column 2:
PL/SQL: Statement ignored
What's wrong?
1) Never create objects in the SYS or SYSTEM schema. Those are reserved for Oracle. If you want to create objects, create a new schema first.
2) When you see that a procedure has been created with compilation errors in SQL*Plus, type show errors to see the errors.
3) The error appears to be that your SELECT statement is trying to write to the fullname parameter. But that parameter is defined as an IN parameter, not IN OUT, so it is read-only. If you define the parameter as IN OUT, though, you could not pass a string constant to the procedure, you'd need to define a local variable in your calling block. It doesn't make a lot of sense to have a procedure that doesn't do anything other than call dbms_output since there is no guarantee that anyone will see the data written to that buffer. My guess is that you really want a function that returns a normalized name. Something like
CREATE OR REPLACE FUNCTION NormalizeName( p_full_name IN VARCHAR2 )
RETURN VARCHAR2
IS
BEGIN
RETURN TRIM( p_full_name );
END;
which you can then call
DECLARE
l_normalized_name VARCHAR2(100);
BEGIN
l_normalized_name := NormalizeName( 'Alice Wonderland ' );
dbms_output.put_line( l_normalized_name );
END;
If you really need a procedure because this is a homework assignment
CREATE OR REPLACE PROCEDURE NormalizeName( p_fullname IN VARCHAR2 )
AS
BEGIN
dbms_output.put_line( TRIM( p_fullname ));
END;
In the real world, you should only be using procedures when you want to manipulate the state of the database (i.e. you're doing INSERT, UPDATE, DELETE, MERGE, etc.). You use functions when you want to perform calculations without changing the state of the database or when you want to manipulate data passed in parameters.

Variable in UPDATE oracle in procedure : invalid identifier

I don't understand why service is complaining with
Fehler(36,11): PL/SQL: ORA-00904: "FOUND_VP": invalid identifier
Variable is declared in the first begin...
Is it not possible to use variable directly in queries ?
when trying store following procedure :
create or replace PROCEDURE fpwl_update_vp(
my_zn IN NUMBER, my_verwaltung IN VARCHAR2 , my_variante IN NUMBER, my_vp IN NUMBER
) IS
BEGIN
DECLARE
search_VP IFT_INFO_LAUF.VP%TYPE;
found_VP IFT_INFO_LAUF.VP%TYPE;
INFOversion number := 25;
BEGIN -- search SYFA_VP
SELECT SYFA_VP
INTO found_VP
FROM FPWL_VP_MAPPING
WHERE INFO_VP=search_VP ;
exception
when no_data_found then
dbms_output.put_line ('Kein SYFA VP : Importiere aus SYFA');
--found_VP:=:=cus_info25.pa_info_data.fn_insert_syfa_vp(my_vp,25);
WHEN OTHERS THEN
ROLLBACK;
RETURN;
END; -- SYFA VP
-- Update VP
UPDATE IFT_INFO_LAUF
SET vp = found_VP
WHERE id_kopf IN
(SELECT id_kopf
FROM ift_info_kopf
WHERE fahrtnummer= my_zn
AND verwaltung= my_verwaltung
AND variante = my_variante
)
;
--COMMIT;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
END ;
Your problem is that found_VP is going out of scope.
Move the contents of the "DECLARE" block to just after the "IS":
create or replace PROCEDURE fpwl_update_vp(
my_zn IN NUMBER, my_verwaltung IN VARCHAR2 , my_variante IN NUMBER, my_vp IN NUMBER
) IS
search_VP IFT_INFO_LAUF.VP%TYPE;
found_VP IFT_INFO_LAUF.VP%TYPE;
INFOversion number := 25;
BEGIN
BEGIN -- search SYFA_VP
etc
Make sure that
FPWL_VP_MAPPING.SYFA_VP
is the same type with
IFT_INFO_LAUF.VP
and make sure that
SELECT SYFA_VP INTO found_VP FROM FPWL_VP_MAPPING WHERE INFO_VP=search_VP ;
does not return multiple rows.
But I doubt that is the case with the error that you have given.
Since the error message refers to line 36 and the reference to found_VP in your code sample is on line 18, you've omitted the part of the code that actually has the problem.
It looks like you have a scope problem; you're declaring found_VP in an inner block (one level of DECLARE/BEGIN/END) and referring to it outside that block, either in the parent block or another one at the same level. The issue isn't where you're selecting into found_VP, it's (I think) that you're referring to it again later on, beyond the code you've posted, and therefore outside the block the variable is declared in.
To demonstrate, I'll declare l_name in an inner block, as you seem to have done:
create or replace procedure p42 is
begin
declare
l_name all_tables.table_name%TYPE;
begin
select table_name
into l_name -- this reference is OK
from all_tables
where table_name = 'EMPLOYEES';
end;
select table_name
into l_name -- this reference errors
from all_tables
where table_name = 'JOBS';
end;
/
Warning: Procedure created with compilation errors.
show errors
Errors for PROCEDURE P42:
LINE/COL ERROR
-------- -----------------------------------------------------------------
12/2 PL/SQL: SQL Statement ignored
13/7 PLS-00201: identifier 'L_NAME' must be declared
14/2 PL/SQL: ORA-00904: : invalid identifier
Notice that the error is reported against line 13, which is in the outer block; it doesn't complain about it in the inner block because it is in-scope there.
So, you need to declare the variable at the appropriate level. As Colin 't Hart says that is probably right at the top, between the IS and the first BEGIN, as that is the procedure-level DECLARE section (it doesn't need an explicit DECLARE keyword).

Resources