SQL statement ignored and missing opening parenthesis - oracle

I get these errors during a creation of a trigger but I don't understand why
create or replace NONEDITIONABLE TRIGGER magazzino_bef_ins
BEFORE INSERT ON MAGAZZINO
FOR EACH ROW
DECLARE
tempcodice varchar2(8);
cacc char(3);
ogg int;
CURSOR cursore_disp IS
SELECT cacciatore, oggetto
FROM TABLE EDDY.disponibilita
WHERE ID_DISPONIBILITA = :NEW.disponibilità;
BEGIN
CURSOR cursore_disp IS
SELECT cacciatore, oggetto
FROM TABLE DISPONIBILITA
WHERE ID_DISPONIBILITA = :NEW.disponibilità;
open cursore_disp;
fetch cursore_disp into cacc,ogg;
temp:= pk_gestione_magazzino.genera_catalogo(cacc,ogg);
:new.codcatalogo:=temp;
END;
The errors are:
Error(5,9): PL/SQL: SQL Statement ignored
Errore(6,20): PL/SQL: ORA-00906: missing opening parenthesis
Errore(9,8): PLS-00103: encountered symbol "CURSORE_DISP" instead of one of the following: := . ( # % ;
I can't understand these errors, I'm just trying to take the values from a table in where the id inserted is equal in the other table.

Here's how. I created test environment which is kind of stupid, but it makes the following code work.
SQL> create table magazzino (disponibilita number, codcatalogo varchar2(8));
Table created.
SQL> create table disponibilita (cacciatore char(3), oggetto number, id_disponibilita number);
Table created.
SQL> create or replace package pk_gestione_magazzino as
2 function genera_catalogo (cacc number, ogg number) return varchar2;
3 end;
4 /
Package created.
SQL> create or replace package body pk_Gestione_magazzino as
2 function genera_catalogo (cacc number, ogg number) return varchar2 is
3 begin
4 return 'Little';
5 end;
6 end;
7 /
Package body created.
Trigger which causes you trouble: no need for a cursor; moreover, you have two of them (was it just a typo)? It looks as if you used it to avoid no data found error. If so, don't do it - it just makes confusion. Handle exceptions properly. By the way, you "forgot" to close the cursor.
SQL> create or replace trigger magazzino_bef_ins
2 before insert on magazzino
3 for each row
4 declare
5 cacc char(3);
6 ogg int;
7 begin
8 select cacciatore, oggetto
9 into cacc, ogg
10 from disponibilita
11 where id_disponibilita = :new.disponibilita;
12
13 :new.codcatalogo := pk_gestione_magazzino.genera_catalogo (cacc, ogg);
14 end;
15 /
Trigger created.
Testing:
SQL> insert into disponibilita values (1, 1, 1);
1 row created.
SQL> insert into magazzino (disponibilita) values (1);
1 row created.
SQL> select * From magazzino;
DISPONIBILITA CODCATAL
------------- --------
1 Little
SQL>
Works, kind of.

Related

PL/SQL procedure with cursor and rowtype

I am working in a games data base. I want to create a procedure which shows the games created between two dates.
I am using a cursor and a rowtype like this:
CREATE OR REPLACE procedure p_games(v_date1 games.date%type, v_date2 games.date%type)
AS
v_games games%rowtype;
CURSOR checkGames IS
SELECT * INTO v_games
FROM games
WHERE date BETWEEN v_date1 AND v_date2;
BEGIN
FOR register IN checkGames LOOP
dbms_output.put_line(register.v_games);
END LOOP;
END;
/
but when I run it the error is
PLS-00302: the component 'V_GAMES' must be declared.
Should I declare it in any other way?
Not exactly like that.
you don't have to declare cursor variable as you're using a cursor FOR loop
you don't select INTO while declaring a cursor; you would FETCH into if you used a different approach (see example below)
Sample table:
SQL> create table games
2 (id number,
3 c_date date
4 );
Table created.
SQL> insert into games (id, c_date) values (1, date '2022-04-25');
1 row created.
Your procedure, slightly modified:
SQL> CREATE OR REPLACE procedure p_games(v_date1 games.c_date%type, v_date2 games.c_date%type)
2 AS
3 CURSOR checkGames IS
4 SELECT *
5 FROM games
6 WHERE c_date BETWEEN v_date1 AND v_date2;
7
8 BEGIN
9 FOR register IN checkGames LOOP
10 dbms_output.put_line(register.id);
11 END LOOP;
12 END;
13 /
Procedure created.
Testing:
SQL> set serveroutput on
SQL> exec p_games(date '2022-01-01', date '2022-12-31');
1
PL/SQL procedure successfully completed.
SQL>
A different approach; as you can notice, a cursor FOR loop is way simpler as Oracle does most of the dirty job for you (opening the cursor, fetching from it, taking care about exiting the loop, closing the cursor):
SQL> CREATE OR REPLACE procedure p_games(v_date1 games.c_date%type, v_date2 games.c_date%type)
2 AS
3 CURSOR checkGames IS
4 SELECT *
5 FROM games
6 WHERE c_date BETWEEN v_date1 AND v_date2;
7
8 v_games checkGames%rowtype;
9 BEGIN
10 open checkGames;
11 loop
12 fetch checkGames into v_games;
13 exit when checkGames%notfound;
14
15 dbms_output.put_line(v_games.id);
16 END LOOP;
17 close checkGames;
18 END;
19 /
Procedure created.
SQL> set serveroutput on
SQL> exec p_games(date '2022-01-01', date '2022-12-31');
1
PL/SQL procedure successfully completed.
SQL>

plsql procedures while executing an error invalid identifier 00904

Error message
CREATE TABLE DEPARTMENT(DID INT,DNAME VARCHAR2(20),DLOC VARCHAR2(20));
INSERT INTO DEPARTMENT VALUES(101,'SRINATH','HINDUPUR');
INSERT INTO DEPARTMENT VALUES(102,'SAINATH','ANANTAPUR');
create or replace PROCEDURE ADD_DEPARTMENT
(P_DID IN DEPARTMENT.DID%TYPE,
P_DNAME IN DEPARTMENT.DNAME%TYPE,
P_DLOC IN DEPARTMENT.DLOC%TYPE,
P_ERROR_MSG OUT VARCHAR2)
IS
BEGIN
INSERT INTO DEPARTMENT(DID,DNAME,DLOC)VALUES(P_DID,P_DNAME,P_DLOC);
COMMIT;
EXCEPTION
WHEN OTHERS THEN
P_ERROR_MSG:=SQLERRM;
END ADD_DEPARTMENT;
iam writing a simple procedure try to excute but it shows object_id:invalid identifier how i can solve
complete procedure execution image
One of your column names may be wrong in the parameter list/insert. Try just using varchar2 for all of them and see if that helps
create or replace PROCEDURE ADD_DEPT2
(P_DEPTNO IN VARCHAR2,
P_DNAME IN VARCHAR2,
P_LOC IN VARCHAR2,
P_ERROR_MSG OUT VARCHAR2)
IS
BEGIN
INSERT INTO DEPT1(DEPTNO,DNAME,LOC)VALUES(P_DEPTNO,P_DNAME,P_LOC);
COMMIT;
EXCEPTION
WHEN OTHERS THEN
P_ERROR_MSG :=SQLERRM;
END ADD_DEPT2;
"it will come same error can be displayed"
No, no it won't. Let's prove it by running the code you posted.
Here is your table:
SQL> CREATE TABLE DEPARTMENT(DID INT,DNAME VARCHAR2(20),DLOC VARCHAR2(20));
Table created.
SQL> INSERT INTO DEPARTMENT VALUES(101,'SRINATH','HINDUPUR');
1 row created.
SQL> INSERT INTO DEPARTMENT VALUES(102,'SAINATH','ANANTAPUR');
1 row created.
SQL>
Here is your procedure:
SQL> create or replace PROCEDURE ADD_DEPARTMENT
2 (P_DID IN DEPARTMENT.DID%TYPE,
3 P_DNAME IN DEPARTMENT.DNAME%TYPE,
4 P_DLOC IN DEPARTMENT.DLOC%TYPE,
5 P_ERROR_MSG OUT VARCHAR2)
6 IS
7 BEGIN
8 INSERT INTO DEPARTMENT(DID,DNAME,DLOC)VALUES(P_DID,P_DNAME,P_DLOC);
9 COMMIT;
10 EXCEPTION
11 WHEN OTHERS THEN
12 P_ERROR_MSG:=SQLERRM;
13 END ADD_DEPARTMENT;
14 /
Procedure created.
SQL>
And lo! not only does it compile but it runs without error too.
SQL> set serveroutput on
SQL> declare
2 v varchar2(128);
3 begin
4 add_department(666, 'Area 51', 'Roswell', v);
5 end;
6 /
PL/SQL procedure successfully completed.
SQL> select * from department;
DID DNAME DLOC
---------- -------------------- --------------------
101 SRINATH HINDUPUR
102 SAINATH ANANTAPUR
666 Area 51 Roswell
SQL>
So once again I ask, what is the problem?
"PLS-00905: object SCOTT.ADD_DEPARTMENT is invalid"
In SQL*Plus:
Connect as SCOTT
alter procedure add_department compile;
show errors
Or apply the equivalent sequence for whatever IDE you use to write your code.

Concatenate String with a column in trigger

I have a table called TBL_CAS. In that, FLD_ID as auto increment column and another column is called FLD_CAS_CODE. Now I need to add CAS- as a prefix to FLD_ID and Insert into FLD_CAS_CODE. I need to do this in trigger. I was tried with the below code, But the data in not inserting, What is the problem ?
CREATE OR REPLACE TRIGGER TBL_CAS_TRG
BEFORE INSERT ON TBL_CAS
FOR EACH ROW
BEGIN
:NEW.FLD_CAS_CODE := TO_CHAR ('CAS')||'-'||:NEW.FLD_ID;
END;
I mean `"cas-"+"fld_id"="cas-fld_id"'
You don't need to put TO_CHAR() around things which are already charcater datatypes. But you should cast the numeric identifier (rather than relying on implicit conversion):
:NEW.FLD_CAS_CODE := 'CAS-'||TRIM(TO_CHAR (:NEW.FLD_ID));
which part isn't working exactly? as your trigger seem to work just fine.
SQL> create table TBL_CAS( FLD_ID number, FLD_CAS_CODE varchar2(20));
Table created.
SQL> CREATE OR REPLACE TRIGGER TBL_CAS_TRG
2 BEFORE INSERT ON TBL_CAS
3 FOR EACH ROW
4 BEGIN
5 :NEW.FLD_CAS_CODE := TO_CHAR ('CAS')||'-'||:NEW.FLD_ID;
6 END;
7 /
Trigger created.
SQL> insert into TBL_CAS (fld_id) values (1001);
1 row created.
SQL> select * From TBL_CAS;
FLD_ID FLD_CAS_CODE
---------- --------------------
1001 CAS-1001
SQL>
This will also work fine:
CREATE OR REPLACE TRIGGER TBL_AREA_CODES_TRG
BEFORE INSERT ON TBL_AREA_CODES
FOR EACH ROW
BEGIN
:NEW.OBRM_AREA_CODE := :NEW.STATE_CODE ||'-'||:NEW.DIST_CODE ||'-'||:NEW.CITY_CODE ||'-'||:NEW.AREA_CODE ;
END;

Oracle, object table & nested tables

Say I have 2 objects MY_OBJ, MY_NESTED_TABLE_OBJ
CREATE OR REPLACE TYPE MY_NESTED_TABLE_OBJ IS TABLE OF VARCHAR2(100);
CREATE OR REPLACE TYPE MY_OBJ AS OBJECT (
simple_atribute NUMBER(6),
table_attribute MY_NESTED_TABLE_OBJ,
MEMBER PROCEDURE doStuff(text VARCHAR2)
) NOT FINAL INSTANTIABLE;
MY_OBJ's table
CREATE TABLE TBL_MY_OBJ OF MY_OBJ
( CONSTRAINT PK_simple_atribute PRIMARY KEY(simple_atribute))
NESTED TABLE table_attribute STORE AS attribute_nst;
How do I insert a VARCHAR2(100) into the nested table belonging to table_attribute?? What is the sintax??
Doing a simple insert like: INSERT INTO attribute_nst VALUES ('some text'); gives the error
cannot reference nested table column's storage table
What i want is to do insert from within PROCEDURE doStuff(text VARCHAR2), i've tried:
INSERT INTO SELF.attribute_nst VALUES (text);
INSERT INTO attribute_nst VALUES (text);
INSERT INTO table_attribute VALUES (text);
...and other combination and no nothing, so please help!
SQL> CREATE OR REPLACE TYPE BODY MY_OBJ AS
2 member procedure doStuff(text varchar2) is
3 begin
4 table_attribute.extend(1);
5 table_attribute(table_attribute.count) := text;
6 end;
7 end;
8 /
Type body created.
SQL> declare
2 l_my_obj My_Obj := My_Obj(1,MY_NESTED_TABLE_OBJ());
3 begin
4 l_my_obj.doStuff('abc');
5 l_my_obj.doStuff('def');
6
7 insert into tbl_my_obj values (l_my_obj);
8 end;
9 /
PL/SQL procedure successfully completed.
SQL> select * from tbl_my_obj;
SIMPLE_ATRIBUTE
---------------
TABLE_ATTRIBUTE
------------------------------------------------------------
1
MY_NESTED_TABLE_OBJ('abc', 'def')
Try this
insert into tbl_my_obj values (1, new my_nested_table_obj(text1, text2));

Create Oracle procedure error - declare custom type

I'm attempting to create a procedure in Oracle Express Server (Application Express 2.1.0.00.39) using the web interface.
This is the SQL I'm running via the SQL Commands option in the web interface
CREATE OR REPLACE PROCEDURE my_procedure (listOfNumbers num_list,
v_value varchar2)
IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
UPDATE my_table
SET my_column = v_value
WHERE my_row_id IN (SELECT column_value
FROM TABLE(listOfNumbers));
COMMIT;
END;
UPDATE:
Changed SELECT column_value FROM TABLE to SELECT column_value FROM TABLE(listOfNumbers) but now I get the following error:
PLS-00201: identifier 'num_list' must
be declared
UPDATE 2:
Here is how I created my type:
CREATE OR REPLACE TYPE "num_list" as table of NUMBER(38,1)
/
Seems the error is being caused on the parameter declaration line:
(listOfNumbers num_list, v_value varchar2)
Below is the object details as displayed by the Oracle Database Express Edition web interface.
Try ...TABLE(CAST(listOfNumbers AS num_list)).
The SQL parser simply sees a bind placeholder in place of listOfNumbers, and since it's a custom type you need to tell it what type it is.
This will only work if num_list has been defined as a type in the schema, not just declared as a type in a PL/SQL block.
Your code works - providing the array type has been declared correctly (see below). As you are still having a problem I suspect that is where you are going wrong. But you need to post the code you are using to create the NUM_LIST type in order for us to correct it.
My test data:
SQL> select * from my_table
2 /
MY_COLUMN MY_ROW_ID
-------------------- ----------
APC 1
XYZ 2
JFK 3
SQL>
In order to use a type in a SQL statement we must create it as a SQL object:
SQL> create type num_list as table of number;
2 /
Type created.
SQL>
SQL>
SQL> create or replace procedure my_procedure
2 (listofnumbers num_list,
3 v_value varchar2)
4 is
5 begin
6
7 update my_table
8 set my_column = v_value
9 where my_row_id in (select column_value
10 from table(listofnumbers));
11
12 end;
13 /
Procedure created.
SQL>
Executing the procedure:
SQL> declare
2 n num_list := num_list(1,3);
3 begin
4 my_procedure (n , 'FOX IN SOCKS');
5 end;
6 /
PL/SQL procedure successfully completed.
SQL>
And lo!
SQL> select * from my_table
2 /
MY_COLUMN MY_ROW_ID
-------------------- ----------
FOX IN SOCKS 1
XYZ 2
FOX IN SOCKS 3
SQL>
Apparently I was creating the type with quotes around the name:
The following didn't work:
CREATE OR REPLACE TYPE "NUMBER_T" as table of NUMBER(38,1)
When I did it without the quotes and then created the procedure, it was able to recognize it.
The following did work:
CREATE OR REPLACE TYPE NUMBER_T as table of NUMBER(38,1)
I'm not sure why, but it worked.

Resources