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.
Related
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
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;
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.
I am trying to delete data from two related tables - primary key in the table users and foreign key in the table login - but I'm getting error PL/SQL: ORA-00933: SQL command not properly ended.
Create table users and primary key:
/* table user*/
create table users (id_user number(10) not null,
name_user varchar(30) not null);
/* primary key */
alter table users add constraint user_pk primary key (id_user);
Create table login and primary key and foreign key:
/* table login*/
create table login (id_login number(10) not null,
id_user_login number(10) not null,
email_login varchar(20) not null,
password_login varchar(20) not null);
/* primary key */
alter table login add constraint login_pk primary key (id_login);
/* foreign key reference to user*/
alter table login add constraint login_fk_user foreign key (id_user_login)
references users(id_user) on delete cascade;
Procedure to create session with table users/login, which works:
PROCEDURE create_user_session( p_name IN VARCHAR2,
p_email IN VARCHAR2,
p_pass IN VARCHAR2,
p_error OUT NUMBER,
p_msg_error OUT VARCHAR2)
IS
BEGIN
p_error := 0;
INSERT ALL
INTO users (id_user, name_user) VALUES(seq_user.NEXTVAL,p_name)
INTO login(id_login, id_user_login, email_login, pass_login)
VALUES(seq_login.NEXTVAL, seq_user.CURRVAL, p_email, p_pass)
SELECT * FROM DUAL COMMIT;
EXCEPTION
WHEN OTHERS THEN
p_error := 1;
p_msg_error := 'Error!'||SQLERRM;
END create_user_session;
Now I want to delete this session, but I have error PL/SQL: ORA-00933: SQL command not properly ended from this procedure:
PROCEDURE delete_user_session(
p_id_user IN NUMBER,
p_error OUT NUMBER,
p_msg_error OUT VARCHAR2)
IS
BEGIN
p_error := 0;
DELETE FROM users, login USING users
INNER JOIN login WHERE users.id_user = p_id_user
AND login.id_user_login = p_id_user;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
p_error := 1;
p_msg_error := 'Error!'||SQLERRM;
END delete_user_session;
I have this image from SQL developer to show the error (red squiggle underline on the s, in DELETE FROM users, login ... if you can't see the image):
What am I doing wrong?
You can't delete from two tables in one statement - there is no delete equivalent of insert all. (Unless you have constraints that cascade the delete, or a trigger that does that manually). The documentation shows that your syntax is not valid, as there is no path to specify more than one table.
You will need to have two delete statements, removing the records from the child table first:
DELETE FROM login
WHERE login.id_user_login = p_id_user;
DELETE FROM users
WHERE users.id_user = p_id_user;
You could change your foreign key constraint to delete cascade:
alter table login add constraint login_fk_user foreign key (id_user_login)
references users(id_user) on delete cascade;
... which would mean you would only have to explicitly delete from the users table; but that may not actually be what you want, as it removes one level of validation - you may want to prevent a parent key being accidentally removed if it has children. Issuing two deletes doesn't really hurt here.
Incidentally, your first procedure is not committing, which you might be expecting. In this line:
...
SELECT * FROM DUAL COMMIT;
... the COMMIT is interpreted as an alias for the DUAL table, not a separate command. You would need a semicolon after DUAL, and preferably a new line for the COMMIT;. But it's generally considered better not to commit in a procedure, and let the top-level caller decide whether to commit or roll back to preserve data integrity.
I'm trying to auto_increment the cust_id field in the following table:
CREATE TABLE A113222813_CUSTOMERS (
CUST_ID NUMBER(10) PRIMARY KEY,
CUST_FNAME VARCHAR2(20),
CUST_SNAME VARCHAR2(20),
CUST_UNAME VARCHAR2(30) NOT NULL,
CUST_PASS VARCHAR2(40) NOT NULL
)
I create the following sequence and trigger to handle this:
CREATE SEQUENCE CUST_SEQ START WITH 1 INCREMENT BY 1 NOCYCLE;
CREATE OR REPLACE TRIGGER CUST_TRG
BEFORE INSERT ON A113222813_CUSTOMERS
FOR EACH ROW
BEGIN
:NEW.CUST_ID := CUST_SEQ.NEXTVAL;
END;
But it keeps throwing the following error:
Error(2,30): PLS-00357: Table,View Or Sequence reference 'CUST_SEQ.NEXTVAL' not allowed
in this context
Any idea what I am doing wrong?
This is not possible before 11g. You can use sequence_name.NEXTVAL in regular assignments from 11g not before that, and that by the following:
select CUST_SEQ.NEXTVAL into :NEW.CUST_ID from dual;