Oracle SQL: Invalid table name when creating a trigger - sql

I created this 4 tables:
create table terminatedEmployees (
empid number primary key,
dept number,
empname varchar2(50),
salary number
);
create table employees (
empid number primary key,
dept number,
empname varchar2(50),
salary number
);
create table payroll (
empid number primary key,
salary number,
CONSTRAINT fk_payemploy
FOREIGN KEY (empid)
REFERENCES employees(empid)
);
create table salaryAudit (
empid number primary key,
oldsal number,
newsal number,
datechanged date,
changedby varchar2(25),
CONSTRAINT fk_salaryaudit
FOREIGN KEY (empid)
REFERENCES employees(empid)
);
and now I'm trying to create a trigger in order to update two of them when employees table is updated:
CREATE TRIGGER trigger_updated_employees
AFTER UPDATE ON employees
FOR EACH ROW
when (old.salary != new.salary)
BEGIN
UPDATE INTO salaryAudit (newsal, oldsal)
VALUES(:new.salary, :old.salary);
UPDATE INTO payroll (salary)
VALUES(:new.salary);
END;
But I'm getting the error:
2/5 PL/SQL: SQL Statement ignored
2/12 PL/SQL: ORA-00903: invalid table name
4/5 PL/SQL: SQL Statement ignored
4/12 PL/SQL: ORA-00903: invalid table name
The three tables I'm calling in the trigger are ok and other triggers I created work...

Try something like this:
CREATE TRIGGER TRIGGER_UPDATED_EMPLOYEES
AFTER UPDATE ON EMPLOYEES
FOR EACH ROW
WHEN (OLD.SALARY <> NEW.SALARY)
BEGIN
MERGE INTO PAYROLL p
USING (SELECT :NEW.EMPID AS EMPID FROM DUAL) d
ON (p.EMPID = d.EMPID)
WHEN NOT MATCHED THEN
INSERT (EMPID, SALARY)
VALUES (:NEW.EMPID, :NEW.SALARY)
WHEN MATCHED THEN
UPDATE
SET SALARY = :NEW.SALARY;
MERGE INTO SALARYAUDIT a
USING (SELECT :NEW.EMPID AS EMPID FROM DUAL) d
ON (a.EMPID = d.EMPID)
WHEN NOT MATCHED THEN
INSERT (EMPID, OLDSAL, NEWSAL, DATECHANGED, CHANGEDBY)
VALUES (:NEW.EMPID, :OLD.SALARY, :NEW.SALARY, SYSDATE, 'SOME_USER')
WHEN MATCHED THEN
UPDATE
SET OLDSAL = :OLD.SALARY,
NEWSAL = :NEW.SALARY,
DATECHANGED = SYSDATE,
CHANGEDBY = 'SOME_USER';
END TRIGGER_UPDATED_EMPLOYEES;
Share and enjoy.

I got it working just correcting the UPDATE statements syntax and modifying the condition as #BobJarvis suggested, this is the final result:
CREATE TRIGGER trigger_updated_employees
AFTER UPDATE OF salary ON employees
FOR EACH ROW
when (old.salary <> new.salary)
BEGIN
UPDATE salaryAudit
SET (newsal, oldsal)
VALUES (:new.salary, :old.salary)
WHERE (salaryAudit.empid = old.empid);
UPDATE payroll
SET (salary)
VALUES (:new.salary)
WHERE (payroll.empid = old.empid);
END;
The concept is the same that #BobJarvis proposed but a lot simpler. Thanks

Related

Can't figure out Oracle update query involving two different tables

The SQL relation between two table is like below:
CREATE TABLE meve_hall (
hallNo NUMBER,
hallName varchar(20),
seatCapacity NUMBER,
PRIMARY KEY(hallNo)
)
CREATE TABLE meve_student (
stuId NUMBER,
name varchar(20),
dept varchar(20),
hallNo NUMBER,
PRIMARY KEY(stuId),
FOREIGN KEY(hallNo) REFERENCES meve_hall(hallNo)
)
Now the question is:
Change the hallName= 'Ziaur' of those students who is in dept='CSE'
You can write an UPDATE statement WHERE hallNo IN and a subquery to get the hallNo based on dept = 'CSE'.
UPDATE meve_hall SET hallName = 'Ziaur'
WHERE hallNo IN (SELECT hallNo FROM meve_student WHERE dept = 'CSE')
Demo here.

How to UPDATE column with ROW_NUMBER() in Teradata?

I'm having a table like this
Create table test1(emp_id decimal(5,0), emp_name varchar(20));
Insert into test1(2015,'XYZ');
Insert into test1(2016,'XYZ2');
Now I want to update emp_id to row_number()
or
add new column into same table like (emp_no integer) to row_number().
can anyone please tell me the query for this?
You need to use UPDATE FROM:
UPDATE test1
FROM
( SELECT ROW_NUMBER() OVER (ORDER BY emp_id) AS rn,
emp_id
FROM test1
) AS src
SET emp_id = src.rn
WHERE test1.emp_id = src.emp_id -- must be unique column(s)
Btw, instead of updating all rows of a table it might be better to INSERT/SELECT or MERGE the SELECT into a new table. You must do it if there's no unique column, you should if emp_id is the PI of your table (otherwise performance will be horrible).
Create table test1(
emp_id decimal(5,0),
emp_name varchar(20),
emp_no INTEGER GENERATED ALWAYS AS IDENTITY
(START WITH 1
INCREMENT BY 1
)
);
Insert into test1(2015,'XYZ1',2);
Insert into test1(2016,'XYZ2',2);
Insert into test1(2015,'XYZ3',null);
Insert into test1(2016,'XYZ4',null);

Delete child table records based on column size in parent table in oracle

I have a scenario like this :
I have three tables:
CREATE TABLE DEPT(DEPT_PK NUMBER NOT NULL,DEPT_NAME VARCHAR(10),DESCRIPTION VARCHAR(50));
CREATE TABLE EMPLOYEE(EMPLOYEE_PK NUMBER(4) NOT NULL PRIMARY KEY,DEPT_PK NUMBER(4),EMP_NAME VARCHAR2(50),ADDRESS VARCHAR2(200));
CREATE TABLE SALARY(SALARY_PK NUMBER NOT NULL,EMP_PK NUMBER(4),net_salary number(5,2));
Now i want to delete the record from dept table and whose dept_pk size is 4 and modify the table's dept_pk size to 3.
Note that emp table has dept_pk as foreign key and salary table has emp_pk as foreign key.
I need to write a pl/sql procedure or sql query for this.
Thanks in advance.
So you have 1st to delete from SALARY:
delete from SALARY where EMP_PK in
(
select EMPLOYEE_PK
from EMPLOYEE
where DEPT_PK in
(
select DEPT_PK from DEPT where length(DEPT_PK) = 4
);
);
Then from EMPLOYEE:
delete from EMPLOYEE
where DEPT_PK in
(
select DEPT_PK from DEPT where length(DEPT_PK) = 4
);
And now from DEPT:
delete from DEPT where length(DEPT_PK) = 4;
EDIT : if you really want to use PL/SQL, you just have to enclose the following code into begin and end for one shot execution:
begin
delete from SALARY where EMP_PK in
(
select EMPLOYEE_PK
from EMPLOYEE
where DEPT_PK in
(
select DEPT_PK from DEPT where length(DEPT_PK) = 4
);
);
delete from EMPLOYEE
where DEPT_PK in
(
select DEPT_PK from DEPT where length(DEPT_PK) = 4
);
delete from DEPT where length(DEPT_PK) = 4;
end;
/
or create a procedure for re-usability: add create or replace procedure proc_name is before begin.

PL/SQL creating a trigger problems

I have to create a trigger on an Employee table. If an INSERT or UPDATE statement is issued for the Employee table the trigger launches and makes sure that the value of 'salary' field meets the criteria in the job_min_sal table. After trying over and over I got a mutating table error and now am very frustrated and don't know what to do.
JOB_MIN_SALARY TABLE:
JOB VARCHAR2(50) PRIMARY KEY
MIN_SAL NUMBER(7,2) NOT NULL
The JOB_MIN_SAL table is populated with a variety of job titles and salaries. I am confused working with my trigger and wondering if I could get some assistance where to go from here
CREATE OR REPLACE TRIGGER employee_job_salary
BEFORE INSERT OR UPDATE OF SALARY on employee
FOR EACH ROW
DECLARE
v_salary NUMBER;
BEGIN
SELECT minimum_salary
INTO v_salary
FROM job_min_salary
WHERE UPPER(job) = UPPER(:NEW.job);
I know I am really far off I am just looking for help as for what this requires and what steps I need to take to get this. Thanks!
The EMPLOYEE table:
(
EMPLOYEE_ID NUMBER(4)
EMPLOYEE_NAME VARCHAR2(20)
JOB VARCHAR2(50)
MANAGER_ID NUMBER(4)
HIRE_DATE DATE
SALARY NUMBER(9)
COMMISION NUMBER(9)
DEPARTMENT_ID NUMBER(4)
);
i am supposing you are doing something like
comparing new salary with min salary criterion and update only if :new.SALARY >= v_salary
what are you doing if this is not met, are u trapping an exception or just ignoring the error or returning an error code to debug.
post more info
CREATE TABLE job_min_salary
(
job VARCHAR2(50) PRIMARY KEY,
min_sal NUMBER(7,2) NOT NULL
);
INSERT INTO job_min_salary VALUES('CEO','100');
-- 1 rows inserted.
CREATE TABLE employee
(
employee_id NUMBER(4),
employee_name VARCHAR2(20),
job VARCHAR2(50),
manager_id NUMBER(4),
hire_date DATE,
salary NUMBER(9),
commision NUMBER(9),
department_id NUMBER(4)
);
INSERT INTO employee VALUES(1, 'Name', 'CEO', 1, TO_DATE('2000-01-01', 'YYYY-MM-DD'), 80, 80, 1);
-- 1 rows inserted.
CREATE OR REPLACE TRIGGER employee_job_salary
BEFORE INSERT OR UPDATE OF salary ON employee
FOR EACH ROW
DECLARE
v_salary NUMBER(1);
BEGIN
SELECT 1
INTO v_salary
FROM job_min_salary
WHERE UPPER(job) = UPPER(:NEW.job)
AND :NEW.salary >= min_sal;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR(-20999, 'Salary value is too low for given job');
END;
-- TRIGGER EMPLOYEE_JOB_SALARY compiled
SELECT * FROM employee;
-- 1 Name CEO 1 2000-01-01 00:00:00 80 80 1
UPDATE employee
SET salary = 10
WHERE job = 'CEO';
-- ORA-20999: Salary value is too low for given job
UPDATE employee
SET salary = 100
WHERE job = 'CEO';
-- 1 rows updated.
SELECT * FROM employee;
-- 1 Name CEO 1 2000-01-01 00:00:00 100 80 1

SQL Trigger Recursive update

I have an organizational database where in it each employee have a foreign key to it's boss(FID).
Table declaration:
Create Table Emp(
ID integer,
FID integer,
SALARY integer,
Primary key (ID),
foreign key (FID) references EMP
);
The following sql trigger should update the employees under a boss. And then update their children recursively. but it only updates one level.
CREATE TRIGGER SAL_TRIG ON EMP After UPDATE
as
declare #SALARY int
declare #OLDSAL int
declare #ID int
--use the 'inserted' keyword to access the values inserted into the invoice table
select #OLDSAL = Salary from deleted
select #SALARY = Salary from inserted
select #ID = ID from inserted
BEGIN
UPDATE EMP
SET SALARY = salary + #SALARY - #OLDSAL
WHERE FID = #ID
END
I want to know how to solve this problem.
Thank you.
Assuming this is SQL Server, you need to enable recursive triggers using sp_dboption. See MSDN for more details:
http://msdn.microsoft.com/en-us/library/ms189799.aspx