Compilation error on oracle trigger - sql

I have a table that has employees (oracle SQL), where each employee has a manager (which is represented as a fk of another employee). I want to create a trigger that when an employee is deleted, all employees that have his key in their manager field have their manager changed to null (or -1, or some reserved value). I'm having some trouble figuring out what's wrong with my current code:
EDIT:
I fixed up most of my code, and I was going about it the wrong way. I used the ON DELETE option that was suggested and now everything works fine. Here's my code:
CREATE TABLE EmployeeA
(
employeeID integer,
firstName varchar (255),
lastName varchar (255),
phone integer,
jobTitle varchar (255),
payGrade integer,
fk_EmployeeemployeeID integer,
PRIMARY KEY(employeeID),
FOREIGN KEY(fk_EmployeeemployeeID) REFERENCES EmployeeA (employeeID) ON DELETE SET NULL
);
INSERT INTO EMPLOYEEA VALUES (1, null, 'Powell', 0, 'President', 100, 1);
INSERT INTO EMPLOYEEA VALUES (2, null, 'Hicke', 0, 'Dean (Natural Science)', 100, 1);
INSERT INTO EMPLOYEEA VALUES (3, null, 'Fenves', 0, 'Dean (Engineering)', 100, 1);
INSERT INTO EMPLOYEEA VALUES (4, null, 'Porter', 0, 'Chairman (Computer Science)', 100, 2);
INSERT INTO EMPLOYEEA VALUES (5, null, 'Beckner', 0, 'Chairman (Mathematics)', 100, 2);
INSERT INTO EMPLOYEEA VALUES (6, null, 'Miranker', 0, 'Professor (Computer Science)', 100, 4);
INSERT INTO EMPLOYEEA VALUES (7, null, 'Mok', 0, 'Professor (Computer Science)', 100, 4);
DELETE FROM employeeA WHERE lastName = 'Porter'; 

You don't want to use a trigger here. Use the on delete property of the foreign key. When you define the foreign key constraint, you can specify that you want it to set the child rows to NULL when the parent row is deleted.
SQL> ed
Wrote file afiedt.buf
1 create table employee2(
2 employee_id number primary key,
3 manager_id number,
4 employee_first_name varchar(30),
5 constraint fk_manager_emp
6 foreign key( manager_id )
7 references employee2( employee_id )
8 on delete set null
9* )
SQL> /
Table created.
If we add a boss, a manager (who reports to the boss), and an employee (who reports to the manager)
SQL> insert into employee2( employee_id, manager_id, employee_first_name )
2 values( 1, null, 'Boss' );
1 row created.
SQL> ed
Wrote file afiedt.buf
1 insert into employee2( employee_id, manager_id, employee_first_name )
2* values( 2, 1, 'Emp1' )
SQL> /
1 row created.
SQL> ed
Wrote file afiedt.buf
1 insert into employee2( employee_id, manager_id, employee_first_name )
2* values( 3, 2, 'Emp2' )
SQL> /
1 row created.
then when we delete the manager, the employee's manager_id automatically gets set to NULL
SQL> delete from employee2
2 where employee_first_name = 'Emp1';
1 row deleted.
SQL> select *
2 from employee2
3 where employee_first_name = 'Emp2';
EMPLOYEE_ID MANAGER_ID EMPLOYEE_FIRST_NAME
----------- ---------- ------------------------------
3 Emp2

Related

Problem inserting into table in oracle using PopSQL

The problem i'm having is that using PopSQL, when i insert something into a table it says success but then it inserts nothing into the table by saying 0 rows affected and i can't figure out what is the problem because PopSQL works fine with postgres and Mysql. Any help is much appreciated.
CREATE TABLE employees
(
employee_id NUMBER PRIMARY KEY,
first_name VARCHAR2(30) NOT NULL,
last_name VARCHAR2(30) NOT NULL,
hire_date DATE NOT NULL,
salary NUMBER(8,2) NOT NULL
);
INSERT INTO EMPLOYEES VALUES (100, 'Malik', 'Makkes', '01-JAN-2010', 9000);
COMMIT;
SELECT * FROM employees;
Seem a Sys error to me
Try this :
INSERT INTO employees (employee_id, first_name, last_name, hire_date, salary)
VALUES (100, 'Malik', 'Makkes', '01-JAN-2010', 9000);
COMMIT;
SELECT * FROM employees;
Make sure to change the VALUES clause to match the correct number of columns and data types in the employees table.
As Jonas commented, "date" value (string, actually; you just enclosed some digits and letters into single quotes) looks suspicious. Read his comment once again.
I'm in Croatia. Let's see what happens in my database.
SQL> CREATE TABLE employees
2 (
3 employee_id NUMBER PRIMARY KEY,
4 first_name VARCHAR2(30) NOT NULL,
5 last_name VARCHAR2(30) NOT NULL,
6 hire_date DATE NOT NULL,
7 salary NUMBER(8,2) NOT NULL
8 );
Table created.
SQL> INSERT INTO EMPLOYEES VALUES (100, 'Malik', 'Makkes', '01-JAN-2010', 9000);
INSERT INTO EMPLOYEES VALUES (100, 'Malik', 'Makkes', '01-JAN-2010', 9000)
*
ERROR at line 1:
ORA-01858: a non-numeric character was found where a numeric was expected
Error; can't say I didn't expect it. What does default NLS value (in my database) say about dates?
SQL> select sysdate right_now,
2 to_char(sysdate, 'dd-mon-yyyy') another_Format
3 from dual;
RIGHT_NOW ANOTHER_FORMAT
---------- --------------------
04.02.2023 04-vel-2023
SQL>
Right; format doesn't match, nor does the language. How to fix it?
One option is to use date literal instead of a string:
SQL> INSERT INTO EMPLOYEES VALUES (100, 'Malik', 'Makkes', date '2010-01-01', 9000);
1 row created.
SQL> select * from employees;
EMPLOYEE_ID FIRST_NAME LAST_NAME HIRE_DATE SALARY
----------- --------------- --------------- ---------- ----------
100 Malik Makkes 01.01.2010 9000
SQL>
That works. Another option is to use to_date function with appropriate format model:
SQL> INSERT INTO EMPLOYEES VALUES (100, 'Malik', 'Makkes',
2 to_date('01-jan-2010', 'dd-mon-yyyy', 'nls_date_language = english'), 9000);
1 row created.
SQL> select * from employees;
EMPLOYEE_ID FIRST_NAME LAST_NAME HIRE_DATE SALARY
----------- --------------- --------------- ---------- ----------
100 Malik Makkes 01.01.2010 9000
SQL>
That works too. Yet another option is to alter your session (or, if you must, NLS settings for the whole database, but for that you'll need to talk to your DBA):
SQL> alter session set nls_date_format = 'dd-mon-yyyy';
Session altered.
SQL> alter session set nls_date_language = 'english';
Session altered.
SQL> INSERT INTO EMPLOYEES VALUES (100, 'Malik', 'Makkes', '01-JAN-2010', 9000);
1 row created.
SQL> select * from employees;
EMPLOYEE_ID FIRST_NAME LAST_NAME HIRE_DATE SALARY
----------- --------------- --------------- ----------- ----------
100 Malik Makkes 01-jan-2010 9000
SQL>
Works again.
Now you've seen a few valid ways to insert date value into a date datatype column. Pick one you find the most appropriate. My choice would be a date literal.
On the other hand, if that's not the issue, provide more info (illustrate execution of your code; post exact error you got).

Creating a table gives a "missing right parenthesis" error

I have been getting error "ORA-00907: missing right parenthesis" when I run this create table statement:
create table employee(
primary key(emp_id number(20)),
emp_name varchar(30),
birth_date date CHECK(birth_date>18),
gender varchar(10),
dept_no number(20)
CONSTRAINT fk FOREIGN KEY(dept_no)
REFERENCES department(dept_no),
address varchar(50),
designation varchar(20)
CHECK(designation IN('manager', 'clerk', 'leader', 'analyst', 'designer', 'coder','tester')),
salary number(50)
CHECK(salary>0),
experience number(2),
email_id varchar(30)
CONSTRAINT chk_email
CHECK (REGEXP_LIKE(email_id,'^[A-Za-z0-9_.]+#[A-Za-z]+\.[A-Za-z]{2,4}$'))
);
I have looked up the exact syntax and after checking many times, everything seems to be just perfect but the error still exists. What is wrong?
A little bit of
invalid syntax (position of the primary key keywords),
superfluous foreign key keywords (you'd use them out of line, not inline),
check constraint for the birth_date column is wrong (how can date be larger than 18?),
Oracle suggests us to use varchar2 instead of varchar,
number(50) has too large precision (perhaps you'd rather just skip it).
Once fixed (with a dummy master table):
SQL> CREATE TABLE department
2 (
3 dept_no NUMBER PRIMARY KEY
4 );
Table created.
Employee:
SQL> CREATE TABLE employee
2 (
3 emp_id NUMBER (20) PRIMARY KEY,
4 emp_name VARCHAR2 (30),
5 birth_date DATE,
6 gender VARCHAR2 (10),
7 dept_no NUMBER CONSTRAINT fk_emp_dept REFERENCES department (dept_no),
8 address VARCHAR2 (50),
9 designation VARCHAR2 (20)
10 CHECK
11 (designation IN ('manager',
12 'clerk',
13 'leader',
14 'analyst',
15 'designer',
16 'coder',
17 'tester')),
18 salary NUMBER CHECK (salary > 0),
19 experience NUMBER (2),
20 email_id VARCHAR2 (30)
21 CONSTRAINT chk_email CHECK
22 (REGEXP_LIKE (
23 email_id,
24 '^[A-Za-z0-9_.]+#[A-Za-z]+\.[A-Za-z]{2,4}$'))
25 );
Table created.
SQL>
As of a trigger that checks employee's age, here's how:
SQL> CREATE OR REPLACE TRIGGER trg_bi_emp
2 BEFORE INSERT
3 ON employee
4 FOR EACH ROW
5 BEGIN
6 IF MONTHS_BETWEEN (SYSDATE, :new.birth_date) < 18 * 12
7 THEN
8 raise_application_error (-20000,
9 'Too young; must be at least 18 years of age');
10 END IF;
11 END;
12 /
Trigger created.
SQL> INSERT INTO employee (emp_id, birth_date) VALUES (1, DATE '2020-07-25');
INSERT INTO employee (emp_id, birth_date) VALUES (1, DATE '2020-07-25')
*
ERROR at line 1:
ORA-20000: Too young; must be at least 18 years of age
ORA-06512: at "SCOTT.TRG_BI_EMP", line 4
ORA-04088: error during execution of trigger 'SCOTT.TRG_BI_EMP'
SQL> INSERT INTO employee (emp_id, birth_date) VALUES (1, DATE '1997-07-25');
1 row created.
SQL>

Creating Oracle Database Table with Numeric Permission Level

I am creating an Oracle database with a table called Roles.
I want the Permission_Level row to store values 1,2,3,4, or 5. How to I limit the input to only those numbers? Here is my attempt:
CREATE TABLE ROLES
(
ROLE_ID NUMBER(20) NOT NULL
, ROLE_NAME VARCHAR2(20) NOT NULL
, PERMISSION_LEVEL NUMBER(1,0) NOT NULL
, CONSTRAINT ROLES_PK PRIMARY KEY
(
ROLE_ID
)
ENABLE
);
Check constraint is one option:
SQL> create table roles
2 (role_id number(20) constraint roles_pk primary key,
3 role_name varchar2(20) not null,
4 permision_level int constraint ch_lvl check
5 (permision_level in (1, 2, 3, 4, 5))
6 );
Table created.
Testing:
SQL> insert into roles (role_id, role_name, permision_level) values (1, 'Role 1', 3);
1 row created.
Level 10 doesn't fit:
SQL> insert into roles (role_id, role_name, permision_level) values (2, 'Role 2', 10);
insert into roles (role_id, role_name, permision_level) values (2, 'Role 2', 10)
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.CH_LVL) violated
SQL>

Why is the table view not coming?

I am new to Oracle. The Oracle live SQL shorthand gave ready-made code on the departments and employees model.
I don't understand why the code is not viewing any table although I wrote a select statement. I don't understand the execution protocol.
link
create table departments (
name varchar2(255) not null,
location varchar2(4000),
country varchar2(4000)
)
;
create table employees (
department_id number
constraint employees_department_id_fk
references departments on delete cascade,
name varchar2(50) not null,
email varchar2(255),
cost_center number,
date_hired date,
job varchar2(255)
)
;
insert into departments (
name,
location,
country
) values (
'Security',
'Tanquecitos',
'United States'
);
insert into departments (
name,
location,
country
) values (
'Travel',
'Sugarloaf',
'United States'
);
insert into departments (
name,
location,
country
) values (
'Office of the CEO',
'Dale City',
'United States'
);
insert into departments (
name,
location,
country
) values (
'Security',
'Grosvenor',
'United States'
);
commit;
-- load data
insert into employees (
department_id,
name,
email,
cost_center,
date_hired,
job
) values (
1,
'Gricelda Luebbers',
'gricelda.luebbers#aaab.com',
20,
sysdate - 94,
'Systems Designer'
);
insert into employees (
department_id,
name,
email,
cost_center,
date_hired,
job
) values (
1,
'Dean Bollich',
'dean.bollich#aaac.com',
11,
sysdate - 74,
'Legal Assistant'
);
insert into employees (
department_id,
name,
email,
cost_center,
date_hired,
job
) values (
1,
'Milo Manoni',
'milo.manoni#aaad.com',
21,
sysdate - 68,
'Systems Designer'
);
insert into employees (
department_id,
name,
email,
cost_center,
date_hired,
job
) values (
1,
'Laurice Karl',
'laurice.karl#aaae.com',
78,
sysdate - 73,
'Programmer'
);
select
departments.name department_name,
departments.location location,
departments.country country,
employees.name employee_name,
employees.email email,
employees.cost_center cost_center,
employees.date_hired date_hired,
employees.job job
from
departments,
employees;
This is the output they are showing after running:
Table created.
ORA-02268: referenced table does not have a primary key
1 row(s) inserted.
1 row(s) inserted.
1 row(s) inserted.
1 row(s) inserted.
Statement processed.
ORA-00942: table or view does not exist
ORA-00942: table or view does not exist
ORA-00942: table or view does not exist
ORA-00942: table or view does not exist
ORA-00942: table or view does not exist
Your table departments does not have a primary key, so the constraint in table employees produces an error, and the table employees is not created.
You should refactor your SQL code, adding a proper primary key to the table involved and manage the insert value properly:
create table departments (
id numeric(10) not null
name varchar2(255) not null,
location varchar2(4000),
country varchar2(4000),
CONSTRAINT id PRIMARY KEY (id)
)
;

beginner to sql plus - what am i doing wrong in this query? why am I getting the result as "0 records updated"?

I am trying some question in sql plus in oracle but it is not working and not returning the desired result. can someone please tell me what I am doing wrong?
the question is:-
Develop a query that will identify and mark inactive those customers that have bills overdue by more than 30 days (this can usually be done using a sub-query). Remember, you are only marking a customer as inactive, not actually deleting the customer record from the system.
This is the query I have tried:-
SELECT CUSTID, CUSTFIRSTNAME, CUSTSTATUS FROM CUSTOMER;
UPDATE CUSTOMER
SET CUSTSTATUS='I'
WHERE CUSTID IN
(SELECT CUSTID FROM BILLING
WHERE (SYSDATE - DUEDATE) > 30 AND PAIDDATE IS NULL);
SELECT CUSTID, CUSTFIRSTNAME, CUSTSTATUS FROM CUSTOMER;
values in billing table are these:-
--INSERT STATEMENTS FOR TABLE BILLING
INSERT INTO BILLING(CUSTID,BILLID,BILLAMT,DUEDATE,PAIDAMT,PAIDDATE )
VALUES(1, 1, 30, DATE '2012-07-01', 30, DATE '2012-07-01' );
INSERT INTO BILLING(CUSTID,BILLID,BILLAMT,DUEDATE,PAIDAMT,PAIDDATE )
VALUES(2, 2, 80, DATE '2012-06-25', 0, );
INSERT INTO BILLING(CUSTID,BILLID,BILLAMT,DUEDATE,PAIDAMT,PAIDDATE )
VALUES(3, 3, 50, DATE '2012-04-01', 0, );
INSERT INTO BILLING(CUSTID,BILLID,BILLAMT,DUEDATE,PAIDAMT,PAIDDATE )
VALUES(4, 4, 30, DATE '2012-06-11', 30, DATE '2012-06-11' );
INSERT INTO BILLING(CUSTID,BILLID,BILLAMT,DUEDATE,PAIDAMT,PAIDDATE )
VALUES(5, 5, 50, DATE '2012-04-30', 0, );
INSERT INTO BILLING(CUSTID,BILLID,BILLAMT,DUEDATE,PAIDAMT,PAIDDATE )
VALUES(6, 6, 80, DATE '2012-06-01', 80, DATE '2012-05-30' );
INSERT INTO BILLING(CUSTID,BILLID,BILLAMT,DUEDATE,PAIDAMT,PAIDDATE )
VALUES(7, 7, 30, DATE '2012-06-15', 0, );
INSERT INTO BILLING(CUSTID,BILLID,BILLAMT,DUEDATE,PAIDAMT,PAIDDATE )
VALUES(8, 8, 30, DATE '2012-05-30', 0, );
INSERT INTO BILLING(CUSTID,BILLID,BILLAMT,DUEDATE,PAIDAMT,PAIDDATE )
VALUES(9, 9, 80, DATE '2012-05-25', 0, );
INSERT INTO BILLING(CUSTID,BILLID,BILLAMT,DUEDATE,PAIDAMT,PAIDDATE )
VALUES(10, 10, 50, DATE '2012-04-01', 0, );
these are the structures of BILLING and Customer table:-
SQL> desc customer;
Name Null? Type
------------------------------------------------------------------------ -------- -----------------
CUSTID NOT NULL NUMBER(5)
CUSTSTATUS NOT NULL CHAR(1)
CUSTDELETERZN VARCHAR2(100)
CUSTDELETEDATE DATE
EMPID NOT NULL NUMBER(5)
CUSTFIRSTNAME NOT NULL VARCHAR2(30)
CUSTLASTNAME NOT NULL VARCHAR2(20)
CUSTSTARTDATE DATE
PACKID NOT NULL NUMBER(2)
CUSTPHONE VARCHAR2(12)
CUSTSTREET VARCHAR2(30)
CUSTCITY VARCHAR2(20)
CUSTSTATE CHAR(2)
CUSTZIP NUMBER(5)
CUSTEMAIL VARCHAR2(30)
SQL> desc billing;
Name Null? Type
------------------------------------------------------------------------ -------- -----------------
CUSTID NOT NULL NUMBER(5)
BILLID NOT NULL NUMBER(5)
BILLAMT NOT NULL NUMBER(5)
DUEDATE NOT NULL DATE
PAIDAMT NUMBER(5)
PAIDDATE DATE
I also tried to write " WHERE (SYSDATE - DUEDATE) > 30 AND PAIDDATE ='');"
this didn't work either.
EDIT:-
I inserted NULL in my INSERT statements now and I am getting this error now:-
UPDATE CUSTOMER
*
ERROR at line 1:
ORA-02290: check constraint (D03318785.CC_CUSTOMER_F_CUSTSTATUS) violated
can anyone plz help?
Create customer table is as follows:-
CREATE TABLE CUSTOMER(
custid NUMBER(5) NOT NULL
CONSTRAINT pk_custid PRIMARY KEY,
custstatus CHAR(1) NOT NULL,
custdeleterzn VARCHAR2(100),
custdeletedate DATE,
empid NUMBER(5) NOT NULL,
custfirstname VARCHAR2(30) NOT NULL,
custlastname VARCHAR2(20) NOT NULL,
custstartdate DATE,
packid NUMBER(2) NOT NULL,
custphone VARCHAR2(12),
custstreet VARCHAR2(30),
custcity VARCHAR2(20),
custstate CHAR(2),
custzip NUMBER(5),
custemail VARCHAR2(30));
This statement:
INSERT INTO BILLING(CUSTID,BILLID,BILLAMT,DUEDATE,PAIDAMT,PAIDDATE )
VALUES(5, 5, 50, DATE '2012-04-30', 0, );
is invalid SQL and will not run.
It will not put "nothing" into the column PAIDDATE. You should have gotten a syntax error running them.
If you ignored that and still committed the inserts, the invalid statements will not have been run and thus those rows have not been inserted (and thus no row with a NULL value for PAIDDATE is in the table). Therefor your update is not finding them.
The error ORA-02290: check constraint (D03318785.CC_CUSTOMER_F_CUSTSTATUS means that the values that are allowed for the CUSTSTATUS columns are limited and the value 'I' that you are trying to assign is not one of them. You will need to find you SQL script that created the check constraint so see which values are allowed.
To retrieve the definition of the check constraint you can use the following statement:
select dbms_metadata.get_ddl('CONSTRAINT', 'CC_CUSTOMER_F_CUSTSTATUS')
from dual;
try this:
WHERE DUEDATE < TRUNC(SYSDATE) - 30 AND PAIDDATE IS NULL
Applying functions to column names should be avoided where possible, and you test for a NULL value using IS NULL
In your insert statements you do not fill the last value (Never seen this before). Try setting it explicitly with a null value like this :
INSERT INTO BILLING(CUSTID,BILLID,BILLAMT,DUEDATE,PAIDAMT,PAIDDATE )
VALUES(5, 5, 50, DATE '2012-04-30', 0, NULL);