SQL error Oracle Trigger on Delete - oracle

I am a first timer in Oracle and using Netbean IDE 8 and I am trying to prevent deletion of a Hotel from Hotel Table if Room Table has Room details for the Hotel. These 2 tables are on 2 different sites so have to use trigger. I tried the following code but it throws error like following with sql error on line 6, 10, 13, 14,
[Exception, Error code 6,550, SQLState 65000] ORA-06550: line 4,
column 19: PLS-00049: bad bind variable '' ORA-06550: line 4, column
30: PLS-00103: Encountered the symbol "end-of-file" when expecting one
of the following:
the table structure is
CREATE TABLE Hotel
(
HotelID number not null,
HotelName varchar2(100) not null,
HotelType varchar2(10) not null,
ConstrYear varchar2(10) null,
Country varchar2 (100) not null,
City varchar2 (50) not null,
Address varchar2 (100) not null,
ContactNo varchar2(50) not null,
Email varchar2(100) null,
CONSTRAINT Hotel_pk PRIMARY KEY (HotelID)
);
and for Room
CREATE TABLE Room
(
RoomID number not null,
HotelID raw(16) not null,
RoomNo number not null,
RoomType varchar2(20) not null,
Price numeric(10,2) not null,
RoomDesc varchar2(255) not null,
CONSTRAINT Room_pk PRIMARY KEY (RoomID),
);
What am I doing wrong? Please help.
CREATE OR REPLACE TRIGGER CHECK_Room
BEFORE DELETE on Hotel
FOR each ROW
declare
rowcount number;
begin
SELECT COUNT(HotelID) INTO rowcount
from ROOM#site1
where HotelID = :OLD.HotelID;
if rowcount>0
THEN
Raise_Application_Error (-20100, 'This Hotel has room details in Room table.');
end if;
end;

The below should work for you, provided your database link is in good shape.
I'd recommend staying away from using a reserved word as a variable name. One common convention is to prefix variable names with "v" as in this example.
I'd also recommend qualifying schema names over the database link. THE_USER is a placeholder here as is THE_OTHER_DATABASE. Please replace with site1, etc. as needed.
First create the tables, in your case in two databases:
--This database
CREATE TABLE HOTEL(HOTELID NUMBER);
--(On the other database)
CREATE TABLE ROOM(HOTELID NUMBER);
-- ... Set up database link
CREATE OR REPLACE TRIGGER CHECK_ROOM
BEFORE DELETE ON HOTEL
FOR EACH ROW
DECLARE
V_ROWCOUNT NUMBER;
BEGIN
SELECT COUNT(HOTELID)
INTO V_ROWCOUNT
FROM THE_USER.ROOM#THE_OTHER_DATABASE
WHERE ROOM.HOTELID = :OLD.HOTELID;
IF V_ROWCOUNT > 0
THEN
Raise_Application_Error(-20100, 'This Hotel has room details in Room table.');
END IF;
END;
/
Then test it:
--Here
INSERT INTO HOTEL VALUES(19);
COMMIT;
--There
INSERT INTO ROOM VALUES(19);
COMMIT;
Then:
DELETE FROM HOTEL;
DELETE FROM HOTEL
*
ERROR at line 1:
ORA-20100: This Hotel has room details in Room table.

Related

Bad bind variable in procedure in oracle

I'm trying to create a procedure that inserts a new row in a table deposit/uttag, throws an exception if you are not authorized to do this transaction. I'm supposed to create a function that checks if someone is authorized or not, and then use that function in this procedure.
I keep getting this error which I don't get:
Errors: PROCEDURE DO_UTTAG
Line/Col: 18/22 PLS-00049: bad bind variable 'NEW.PNR'
Line/Col: 18/31 PLS-00049: bad bind variable 'NEW.KNR'
Quick translations:
Saldo=balance
konto= account
pnr= personal number
knr= customer number
belopp= amount
These are the main tables:
CREATE TABLE bankkund(
PNR VARCHAR2(11) PRIMARY KEY,
FNAMN VARCHAR2(25) NOT NULL,
ENAMN VARCHAR2(25) NOT NULL ,
PASSWD VARCHAR2(16) NOT NULL,
UNIQUE(PASSWD));
CREATE TABLE kontotyp(
KTNR NUMBER(6)PRIMARY KEY,
KTNAMN VARCHAR2(20)NOT NULL,
RÄNTA NUMBER(5,2) NOT NULL);
CREATE TABLE konto(
KNR NUMBER(8)PRIMARY KEY,
KTNR NUMBER(6)NOT NULL,
REGDATUM DATE NOT NULL,
SALDO NUMBER(10,2),
FOREIGN KEY(ktnr) REFERENCES kontotyp(ktnr));
CREATE TABLE uttag(
RADNR NUMBER(9) PRIMARY KEY,
PNR VARCHAR2(11)NOT NULL,
KNR NUMBER(8)NOT NULL,
BELOPP NUMBER(10,2),
DATUM DATE NOT NULL,
FOREIGN KEY(pnr) REFERENCES bankkund(pnr),
FOREIGN KEY(knr) REFERENCES konto(knr));
This is the procedure:
create or replace procedure do_uttag (
p_radnr kontoägare.radnr%TYPE,
p_pnr bankkund.pnr%TYPE,
p_knr konto.knr%TYPE,
p_belopp uttag.belopp%TYPE)
as
v_saldo konto.saldo%type;
begin
select saldo
into v_saldo
from konto;
insert into uttag(
radnr, pnr, knr, belopp, datum
) values (
p_radnr, p_pnr, p_knr, p_belopp, SYSDATE
);
if get_behörighet(:NEW.PNR,:NEW.KNR) = 0
then
raise_application_error(-20101, 'Du har inte behörigheten!');
else
update konto
set saldo = v_saldo - p_belopp;
dbms_output.put_line('Saldot är nu = ' ||(v_saldo - p_belopp));
end if;
end;
/
This is the function that I created for authorization:
create or replace function get_behörighet (
p_pnr in bankkund.pnr%type,
p_knr in konto.knr%type)
return number
is
v_pnr bankkund.pnr%type;
v_knr konto.knr%type;
begin
select bankkund.pnr, konto.knr
into v_pnr, v_knr
from bankkund, konto
where bankkund.pnr = p_pnr
and konto.knr = p_knr;
return 1;
exception
when others then
return 0;
end;
/
Would really appreciate the help!!
get_behörighet(:NEW.PNR,:NEW.KNR)
this is a form of addressing fields allowed in triggers

Invalid reference in Oracle database

I am using Oracle database 19c for a project. I have created the alumni table as shown below:
CREATE TABLE Alumni (
ID NUMBER GENERATED ALWAYS AS IDENTITY ,
First_Name varchar2(20) NOT NULL,
Last_Name varchar2(20) NOT NULL,
Gender char(1) NOT NULL,
CHECK (Gender IN('M','F')),
Graduation_Year number NOT NULL,
check (Graduation_Year>=1980 AND Graduation_Year<=2020),
Degree_Course varchar2(255) not null,
Award_Nominated CHAR(1),
CHECK (Award_Nominated IN('Y','N')),
Award_Won CHAR(1),
CHECK (Award_Won IN('Y','N')),
Phone_Number VARCHAR2(15) not null,
Email_Address VARCHAR2(255) not null,
CONSTRAINT ALUM_PK PRIMARY KEY(ID)
);
Then I tried to define a function that will allow me to search by First or last name in a section of the table, shown below:
CREATE OR REPLACE TYPE alum_row_type is object(ID number,First_name varchar2(20),Last_Name
varchar2(20),Phone_number varchar2(15),Email_Address varchar2(255));
CREATE OR REPLACE TYPE t_alum_row_type as table of alum_row_type;
CREATE OR REPLACE FUNCTION Name_Search RETURN t_alum_row_type
IS
L_alum_row t_alum_row_type := t_alum_row_type();
X integer :=0;
BEGIN
FOR R IN (SELECT ID,First_Name, Last_Name,Phone_Number,Email_Address FROM alumni)
LOOP
L_alum_row.extend;
X:=X+1;
L_alum_row(X):= alum_row_type(X.ID,X.First_Name, X.Last_Name, X.Phone_Number, X.Email_Address);
END LOOP;
RETURN L_alum_row;
END;
After running this, I get this error:
LINE/COL ERROR
--------- -------------------------------------------------------------
10/9 PL/SQL: Statement ignored
10/41 PLS-00487: Invalid reference to variable 'X'
Errors: check compiler log
How can I resolve this issue. I am relatively new to PL\SQL, so please explain it simply.
This is not possible
L_alum_row(X):= alum_row_type(X.ID,X.First_Name, X.Last_Name, X.Phone_Number, X.Email_Address);
You are referencing X.ID, X.Phone_Number etc. . . but declared X as an integer. If you are trying to access the current loop record, try with
L_alum_row(X):= alum_row_type(R.ID,R.First_Name, R.Last_Name, R.Phone_Number, R.Email_Address);
As you declared the loop iterator as R for your cursor
FOR R IN (SELECT ID,First_Name, Last_Name,Phone_Number,Email_Address FROM alumni)
You can eliminate the loop altogether by using BULK COLLECT. Thereby reducing the function to basically a single select statement.
function name_search
return t_alum_row_type
is
l_alum_row t_alum_row_type := t_alum_row_type();
begin
select alum_row_type(id,first_name, last_name,phone_number,email_address)
bulk collect
into l_alum_row
from alumni;
return l_alum_row;
end;

Oracle trigger on varchar values not working

I have 2 tables 'label' and 'musician'
CREATE TABLE label
(labId varchar(10) NOT NULL PRIMARY KEY,
labName varchar(20) NOT NULL
);
CREATE TABLE musician
(musId varchar(10) NOT NULL PRIMARY KEY,
musName varchar(30) NOT NULL,
labId varchar(10) NOT NULL,
CONSTRAINT MusLabel FOREIGN KEY (labId) REFERENCES label(labId)
);
I created a trigger to limit the number of musicians a label can have within a
range of 1 to 5; so that for example a label x cannot have 6 musicians:
CREATE OR REPLACE TRIGGER before_musician_insert
BEFORE INSERT ON musician
FOR EACH ROW
DECLARE
total integer;
BEGIN
SELECT COUNT(*) INTO total
FROM musician, label
WHERE musician.labId=label.labId;
IF (total < 0 OR total > 5)
THEN
DBMS_OUTPUT.PUT_LINE('Invalid');
END IF;
END;
/
When I insert a 6th musician into the table with the same label ID, the insert statement does not 'trigger' the TRIGGER and the 6th value is added to the table.
I don't know how to fix this.
I tried a check constraint but with varchar values, it is not working either.
I appreciate your help.
Your code has multiple issues. For instance, it is not accessing :new. The trigger is on the wrong table. It has no error generation.
I might suggest something like this:
CREATE OR REPLACE TRIGGER before_labels_insert
BEFORE INSERT ON labels
FOR EACH ROW
DECLARE
v_total integer;
user_xcep EXCEPTION;
PRAGMA EXCEPTION_INIT( user_xcep, -20001 );
BEGIN
SELECT COUNT(*) INTO v_total
FROM labels l
WHERE l.labId = :new.labId;
IF (v_total >= 5) THEN
DBMS_OUTPUT.PUT_LINE('Invalid');
RAISE user_xcep
END IF;
END;
Your trigger fires BEFORE the insert, so the sixth entry doesn't exist when the query is executed.
If you want to error on the insert of the 6th entry, you can make it an AFTER trigger (and fire once per statement, rather than FOR EACH ROW).

Error at line 4: PL/SQL: SQL Statement ignored

So, i have this trigger:
create or replace TRIGGER COD_MEMBER
BEFORE INSERT ON members
FOR EACH ROW
DECLARE
member_id number;
BEGIN
SELECT seq_member.nextval
INTO member_id
FROM dual;
:new.n_member := member_id;
END;
/​
I am new with this stuff so i´m not sure if i am doing this right.
The error is: Error at line 4: PL/SQL: SQL Statement ignored
I have this table for members:
DROP TABLE members CASCADE CONSTRAINTS;
CREATE TABLE members (
n_member NUMBER(9),
name_level VARCHAR2(100) NOT NULL,
email VARCHAR2(100) NOT NULL,
date_birth DATE NOT NULL,
date_ins DATE NOT NULL,
date_end DATE NOT NULL,
phone_number NUMBER(9) NOT NULL,
name VARCHAR2(100) NOT NULL,
PRIMARY KEY(n_member),
FOREIGN KEY(name_level) REFERENCES level_member(name_member));
I hope you guys can help me ;)
Seems that sequence object seq_member doesnt exists.
If you use SQL*PLus ot SQLcl or SQL Developer you can use show errors command to view full error stack on last on your SQL.

ORACLE -1401 error

I have a stored procedure in Oracle 9i which inserts records in a table. The table has a primary key built to ensure duplicte rows doesnot exists.
I am trying to insert a record by calling this stored procedure and it works first time properly. I am again trying to insert a duplicate record and expecting unique constraint violation error. But I am getting
ORA-01401 inserted value too large for column
I knew its meaning but my query is , if the value inserted is really large then how it got successful in the first attempt.
Table is
CREATE TABLE KEY
(
ID VARCHAR2(25 BYTE),
KEY NUMBER(4) NOT NULL,
INSERT_DATE DATE,
WORK_KEY VARCHAR2(128 BYTE)
)
CREATE UNIQUE INDEX SACHINIDX ON KEY
(ID, KEY)
Call is
EXEC SQL EXECUTE
BEGIN
keyadd(:id, :key, :wkey);
END;
END-EXEC;
Stored Procedure is
PROCEDURE keyadd(id IN VARCHAR2, key IN NUMBER, wkey IN VARCHAR2)
{
BEGIN
INSERT INTO KEY
( ID,
KEY,
INSERT_DATE,
WORK_KEY)
VALUES
(
id,
key,
SYSDATE,
wkey
);
EXCEPTION
ROLLBACK;
COMMIT;
RETURN;
END;
}
First insert sqlca.sqlcode is [0]
Second insert sqlca.sqlcode is [-1401]
CREATE TABLE KEY
(
ID VARCHAR2(25 BYTE),
KEY NUMBER(4) NOT NULL,
INSERT_DATE DATE,
WORK_KEY VARCHAR2(128 BYTE)
);
CREATE UNIQUE INDEX SACHINIDX ON KEY
(ID, KEY);
create or replace PROCEDURE keyadd(id IN VARCHAR2, key IN NUMBER, wkey IN VARCHAR2)
is
BEGIN
INSERT INTO KEY
( ID,
KEY,
INSERT_DATE,
WORK_KEY)
VALUES
(
id,
key,
SYSDATE,
wkey
);
COMMIT;
-- EXCEPTION when others then
-- ROLLBACK;
end keyadd;
/
begin
keyadd('one', 1, '59FC9AD0FA5A8932836824B0489B73252C120301A2205154C096B4EB213FA983D5E500B62A469439');
keyadd('one', 1, '905BD61AAEC986ACF887DBA7C04D650B61A8818ABEBE1720D810B4A426EB9220558B530D5119315F');
end;
/
gives me the expected ORA-00001: Unique Constraint... error, not an ORA-01401. So, without further information its impossible to help.
I don't know the language the procedure was written in, but this part:
EXCEPTION
ROLLBACK;
COMMIT;
RETURN;
raises my eyebrows. Two questions:
What is this supposed to do?
Is your issue solved when you remove those lines?
My best guess is on your second try, you are providing a value for one of the other columns that is too large. Looks like this error will supersede the primary key violation.

Resources