oracle trigger pl sql - sql

I have a database user that contains four tables department, employee, address and contact info, then stored 5 Records in each table, and wrote the PL/SQL Statement for the following:
Stored a record into employee, address and contact using trigger.
the insert into view is not working ! it results in error ? can you guys help me with this ?
this is my code :
-- Create Tables :
CREATE TABLE address (
code int primary key,
city varchar2(30),
street varchar2(30)
);
create table Department (
DepId int primary key ,
Dep_Name varchar2(30) ,
Dep_adress varchar(30));
create table Employee (
Emp_Id int primary key ,
firstName varchar2(30),
lastName varchar2(30),
salary int,
Dep_Id int references Department (DepId),
Code int references address (code));
CREATE TABLE contact_info (
email varchar2(30) primary key ,
phone int ,
EmpId int references Employee (Emp_Id));
-- insert :
insert into Department values (1,'IT','Amman');
insert into Department values (2,'CS','Jerash');
insert into Department values (3,'accounting','Amman');
insert into Department values (4,'managment','Amman');
insert into Department values (5,'employment','Amman');
insert into address values (50,'Amman','AAA');
insert into address values (60,'Amman','AAB');
insert into address values (70,'Amman','AAC');
insert into address values (80,'Jerash','AAD');
insert into address values (90,'Irbid','AAE');
insert into Employee (Emp_Id,firstName,lastName,salary,Dep_Id,Code) values (1,'john' , 'samo' , 1000 , (select DepId from Department where Dep_Name = 'IT'),(select code from address where street = 'AAA'));
insert into Employee (Emp_Id,firstName,lastName,salary,Dep_Id,Code) values (2,'mark' , 'wol' , 2000 , (select DepId from Department where Dep_Name = 'IT'),(select code from address where street = 'AAB'));
insert into Employee (Emp_Id,firstName,lastName,salary,Dep_Id,Code) values (3,'ahmad' , 'moh' , 1100 , (select DepId from Department where Dep_Name = 'IT'),(select code from address where street = 'AAC'));
insert into Employee (Emp_Id,firstName,lastName,salary,Dep_Id,Code) values (4,'maher' , 'imk' , 1700 , (select DepId from Department where Dep_Name = 'CS'),(select code from address where street = 'AAD'));
insert into Employee (Emp_Id,firstName,lastName,salary,Dep_Id,Code) values (5,'ali' , 'geh' , 1200 , (select DepId from Department where Dep_Name = 'CS'),(select code from address where street = 'AAE'));
insert into contact_info values ('john#gmail.com',0785602200, (select Emp_Id from Employee where salary = 1000));
insert into contact_info values ('mark#gmail.com',0785602201, (select Emp_Id from Employee where salary = 2000));
insert into contact_info values ('ahmad#gmail.com',0785602202, (select Emp_Id from Employee where salary = 1100));
insert into contact_info values ('maher#gmail.com',0785602203, (select Emp_Id from Employee where salary = 1700));
insert into contact_info values ('ali#gmail.com',0785602204, (select Emp_Id from Employee where salary = 1200));
-- trigger :
CREATE VIEW vw_address1 AS
SELECT
code,
city,
street
FROM
address;
CREATE OR REPLACE TRIGGER new_trg2
INSTEAD OF INSERT ON vw_address1
FOR EACH ROW
DECLARE
l_code NUMBER;
BEGIN
-- insert a new address first
INSERT INTO address(code,city, street)
VALUES(:NEW.code,:NEW.city, :NEW.street)
RETURNING code INTO l_code;
END;
insert into vw_address1(code,city,street) values (2,'Amman','AAB');

Related

How to use INSERT INTO SELECT

CREATE TABLE EMPLOYEES (
EMPLOYEEID INT NOT NULL,
DEPARTMENTID INT NOT NULL,
);
CREATE TABLE MANAGERS (
EMPLOYEEID INT NOT NULL,
DEPARTMENTID INT NOT NULL,
ALTER_TIMESTAMP TIMESTAMP NOT NULL
);
I want to insert EMPLOYEES.EMPLOYEEID, EMPLOYEES.DEPARTMENTID, ALTER_TIMESTAMP to MANAGERS table using INSERT INTO SELECT. (ALTER_TIMESTAMP col is current time)
I want this result
enter image description here
this is my code
INSERT INTO MANAGERS
(EMPLOYEEID, DEPARTMENTID, ALTER_TIMESTAMP)
SELECT EMPLOYEEID, DEPARTMENTID, to_char(ALTER_TIMESTAMP, 'YYYY-MM-DD HH24:MI:SS:FF3')
FROM EMPLOYEES, DUAL;
but "ORA-00904: "DUAL"."ALTER_TIMESTAMP": invalid identifier"
You have no column named "alter_timestamp" in your table, this is the cause of the error message.
Try the next insert statement:
INSERT INTO MANAGERS
(EMPLOYEEID, DEPARTMENTID, ALTER_TIMESTAMP)
SELECT EMPLOYEEID, DEPARTMENTID, CURRENT_TIMESTAMP
FROM EMPLOYEES;

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)
)
;

How to count records in SQL

Edit: Schema taken/extrapolated from comment below
create table #employees
(
Emp_ID int,
Name varchar(50),
Dept_ID int,
);
create table #departments
(
Dept_ID int,
Dept_Name varchar(50)
);
How do I count the number of employees from table employees that work in each department in table departments and include all departments that have no employees working in them.
Welcome to SO.
This problem is quite simple to solve. The steps would be as follows:
Join the Departments table to the Employees table on the Dept_ID column.
SELECT the Dept_ID and Count() and GROUP BY the Dept_ID field.
In order to return Departments without employees you need to LEFT JOIN this aggregation to the Departments table on the Dept_ID column.
In order to return the value of 0 for departments without employees, use the ISNULL() function.
Please see the below sample script using your schema. Note that this script is written in T-SQL, as you did not mention your server type.
create table #employees
(
Emp_ID int,
Name varchar(50),
Dept_ID int,
);
create table #departments
(
Dept_ID int,
Dept_Name varchar(50)
);
insert into #employees
select 1, 'Pim', 1
union all
select 2, 'Salma', 2;
insert into #departments
select 1, 'IT'
union all
select 2, 'Marketing'
union all
select 3, 'Design'
select
d1.Dept_Name
,isnull(d2.EmployeeCount, 0) as EmployeeCount
from
#departments d1
left join
(
select
d.Dept_ID
,count(e.Dept_ID) as EmployeeCount
from
#departments d
join
#employees e
on e.Dept_ID = d.Dept_ID
group by
d.Dept_ID
)
d2
on d2.Dept_ID = d1.Dept_ID
drop table #employees
drop table #departments
As you have supplied no data please try below and see if this works for you
Create the tables, I don't know if this is similar to your table structure
CREATE TABLE tbl_EMPLOYEES (Empl_Name nvarchar(20), Dept nvarchar(15))
CREATE TABLE tbl_DEPARTMENT (Dept nvarchar(15))
Populate these tables
INSERT INTO tbl_EMPLOYEES Values ('James', 'Finance')
INSERT INTO tbl_EMPLOYEES Values ('Tim', 'HR')
INSERT INTO tbl_EMPLOYEES Values ('Sally', 'Finance')
INSERT INTO tbl_EMPLOYEES Values ('Bob', 'Sales')
INSERT INTO tbl_EMPLOYEES Values ('Sam', 'HR')
INSERT INTO tbl_EMPLOYEES Values ('James', 'Finance')
INSERT INTO tbl_DEPARTMENT Values ('Finance')
INSERT INTO tbl_DEPARTMENT Values ('HR')
INSERT INTO tbl_DEPARTMENT Values ('Sales')
INSERT INTO tbl_DEPARTMENT Values ('IT')
This query will give you the number of people in each department
SELECT Dept, Count(Dept) AS Count
FROM
(
SELECT Dept
FROM tbl_EMPLOYEES
) AS Blah_Blah
GROUP BY Dept

Generating insert statement dynamically based on conditions

I have two separate deployment of Student Table. In one case student table contains department Id and in other case it doesn't contain department Id.
I have a common post deployment script for both cases to insert value in student table.
CREATE TABLE dbo.Student
(
DeptId UNIQUEIDENTIFIER,
StudentName VARCHAR(20)
)
GO
DECLARE #DeptId UNIQUEIDENTIFIER
IF COL_LENGTH('dbo.Department', 'DeptId') IS NOT NULL BEGIN
SELECT #DeptId = DeptId
FROM dbo.Department
WHERE DeptName = 'Computer'
END
INSERT INTO dbo.Student(DeptId, StudentName)
SELECT #DeptId, 'TBAG'
But When I don't have department Id column this script doesn't work
Msg 207, Level 16, State 1, Line 23
Invalid column name 'DeptId'.
You can try something like this,
CREATE TABLE dbo.Student
(
DeptId UNIQUEIDENTIFIER,
StudentName VARCHAR(20)
)
GO
IF Col_length('dbo.Department', 'DeptId') IS NOT NULL
BEGIN
INSERT INTO dbo.Student
(DeptId,
StudentName)
SELECT DeptId,
'TBAG'
FROM dbo.Department
WHERE DeptName = 'Computer'
END
ELSE
BEGIN
INSERT INTO dbo.Student
(StudentName)
SELECT 'TBAG'
END

How to solve single-row subquery returns more than one row

I have an employee table and it contains salary table. I want to give %10 increase to all current employees. I tried to update all employees' salary dates to specific date but I encountered problem with single-row subquery.
My database like this:
CREATE TYPE TEMPORAL_VARCHAR AS OBJECT (
VALID_TIME_LOWER_BOUND DATE,
VALID_TIME_UPPER_BOUND DATE,
VALUE_PART VARCHAR2(50) );
CREATE TYPE TEMPORAL_NUMBER AS OBJECT (
VALID_TIME_LOWER_BOUND DATE,
VALID_TIME_UPPER_BOUND DATE,
VALUE_PART NUMBER );
CREATE TYPE NAME_TYPE AS TABLE OF TEMPORAL_VARCHAR;
CREATE TYPE ADDRESS_TYPE AS TABLE OF TEMPORAL_VARCHAR;
CREATE TYPE DEPARTMENT_TYPE AS TABLE OF TEMPORAL_VARCHAR;
CREATE TYPE MANAGER_TYPE AS TABLE OF TEMPORAL_VARCHAR;
CREATE TYPE SALARY_TYPE AS TABLE OF TEMPORAL_NUMBER;
CREATE TABLE EMPLOYEE (
SSN NUMBER primary key,
NAME NAME_TYPE,
ADDRESS ADDRESS_TYPE ,
BIRTH_DATE DATE,
MANAGER MANAGER_TYPE ,
DEPARTMENT DEPARTMENT_TYPE,
SALARY SALARY_TYPE
)
NESTED TABLE NAME STORE AS NAME_TABLE,
NESTED TABLE ADDRESS STORE AS ADDRESS_TABLE,
NESTED TABLE MANAGER STORE AS MANAGER_TABLE,
NESTED TABLE DEPARTMENT STORE AS DEPARTMENT_TABLE,
NESTED TABLE SALARY STORE AS SALARY_TABLE
;
How to solve this problem? I tried to do this
UPDATE TABLE(
SELECT E.SALARY
FROM EMPLOYEE E
) SAL
SET SAL.VALID_TIME_UPPER_BOUND = '11.16.2015'
WHERE SAL.VALID_TIME_UPPER_BOUND = TO_DATE('12.31.9999','MM.DD.YYYY');
1st it can be duplicate
2nd see sample here
3rd in your code you need bring the where condition into select
UPDATE TABLE(
SELECT E.SALARY
FROM EMPLOYEE E
WHERE ssn in (SELECT ssn FROM EMPLOYEE e
WHERE to_date('01.01.2015','mm.dd.yyyy') in (
SELECT VALID_TIME_UPPER_BOUND FROM TABLE(e.salary)
)
)
) SAL
SET SAL.VALID_TIME_UPPER_BOUND = to_date('01.01.9999','mm.dd.yyyy')
test data
INSERT INTO EMPLOYEE(SSN, salary) values (1, SALARY_TYPE ());
INSERT INTO EMPLOYEE(SSN, salary) values (2, SALARY_TYPE ());
INSERT INTO EMPLOYEE(SSN, salary) values (3, SALARY_TYPE ());
INSERT INTO TABLE(SELECT salary FROM EMPLOYEE
WHERE ssn = 1)
VALUES (to_date('01.01.2005','mm.dd.yyyy'), to_date('01.01.2015','mm.dd.yyyy'), 1);
INSERT INTO TABLE(SELECT salary FROM EMPLOYEE
WHERE ssn = 2)
VALUES (to_date('02.02.2005','mm.dd.yyyy'), to_date('02.02.2015','mm.dd.yyyy'), 2);
INSERT INTO TABLE(SELECT salary FROM EMPLOYEE
WHERE ssn = 3)
VALUES (to_date('03.03.2005','mm.dd.yyyy'), to_date('03.03.2015','mm.dd.yyyy'), 3);
p.s do you really need the complexity?
I solved my problem using iteration like this
BEGIN
FOR employees IN (SELECT SSN FROM EMPLOYEE)
LOOP
UPDATE TABLE(
SELECT E.SALARY
FROM EMPLOYEE E
WHERE E.SSN = employees.SSN
) SAL
SET SAL.VALID_TIME_UPPER_BOUND = '11.16.2015'
WHERE SAL.VALID_TIME_UPPER_BOUND = TO_DATE('12.31.9999','MM.DD.YYYY');
END LOOP;
END;