Merge two tables with same primary key - sql

Example i having some values in Employee with following fields.
CREATE TABLE Department (
D# NUMBER(5) NOT NULL, /* Department number */
DName VARCHAR2(30) NOT NULL, /* Department name */
Manager# CHAR(5) NOT NULL, /* Department manager number */
MSDate DATE, /* Manager start date */
total_staff_number NUMBER(3),
CONSTRAINT Department_PK PRIMARY KEY(D#),
CONSTRAINT Department_CK UNIQUE(DName)
);
CREATE TABLE Employee (
E# CHAR(5) NOT NULL, /* Employee number */
Name VARCHAR2(30) NOT NULL, /* Employee name */
D# NUMBER(5), /* Department number */
CONSTRAINT Employee_PK PRIMARY KEY(E#),
CONSTRAINT Employee_FK2 FOREIGN KEY (D#) REFERENCES Department (D#)
);
In my database. DEPARTMENT = 'SPORTS' = D# = 5, DEPARTMENT = 'GAMES' = D# = 3;
Merging the DEPARTMENT='SPORTS' INTO DEPARTMENT='GAMES' , and manager will still remain the same, the employee.D#=5 will change to employee.D#=3
MERGE INTO EMPLOYEE TARGET
USING EMPLOYEE SOURCE WHERE D#=5 ON (
TARGET.D# = SOURCE.D#;
}
WHEN MATCHED THEN
UPDATE SET SOURCE.D#=3;
UPDATE DEPARTMENT.D# SET total_staff_number = total_staff_number - 1 where DEPARTMENT.D# = SOURCE.D#;
UPDATE DEPARTMENT.D# SET total_staff_number = total_staff_number - 1 where DEPARTMENT.D# = TARGET.D#;
but my logic seem like wrong.
any solution?

Moving the employees from Sports to Games would be simply updating the departpent column to point to the new department. The question is what you are going to do with the dangling department sports afterwards?
For all employees working in Sports, change to Games.
update employee
set d# = 3
where d# = 5;
Count the nr of employees in department Games, and update the employee counter.
update department
set total_staff_number = (
select count(*)
from employee
where d# = 3
)
where d# = 3;

Related

Problem using SQLite Trigger to increment a value

Hi guys i'm new in triggers. I have two tables and i want when add a user that works in an department the value of employees to increase by one in the particular department. But i take an error like "Error while committing new row: No such column user.department_id.
CREATE TABLE department (
department_id INTEGER PRIMARY KEY,
department_name TEXT NOT NULL,
employees INTEGER NOT NULL
);
CREATE TABLE user (
user_id INTEGER PRIMARY KEY,
user_name TEXT NOT NULL,
department_id INTEGER NOT NULL,
FOREIGN KEY (
department_id
)
REFERENCES department (department_id)
);
CREATE TRIGGER inputUser
AFTER INSERT
ON user
BEGIN
UPDATE department
SET employees = employees + 1
WHERE department.department_id = user.department_id;
END;
INSERT INTO user(user_id, user_name, department_id) VALUES(1, "Testuser", 1);
Any help please..
In the trigger, you can use [pseudo-tables new or old] to refer to the row that is being modified:
UPDATE department
SET employees = employees + 1
WHERE department.department_id = new.department_id;
Here is a demo on DB Fiddle.

Define an SQL constraint depending on more than one attribute

I have this defined type and table:
CREATE TYPE emp_role AS ENUM ('Manager','Developer','Accountant','Secretary');
CREATE TABLE employees (
employee_id int NOT NULL UNIQUE,
lastname text NOT NULL,
firstname text NOT NULL,
address text NOT NULL,
hire_date date NOT NULL,
salary numeric NOT NULL CHECK(salary > 1.500),
emp_role emp_role,
department_id int NOT NULL
);
I want to create a constraint on this table, without modifying its definition, that depends at the same time on the attributes hire_date, salaryand emp_role, this means for example that employees with emp_role of Manager hired after 2019-21-11 can't have salarybigger than 15.000so a query like this should return an error:
INSERT INTO employees VALUES(2,'foo','bar','foostreet','2019-12-20',18.0000,'Manager',3);
I'm not familiar with how to do this
You can create a multi-column check constraint as follows:
CREATE TYPE emp_role AS ENUM ('Manager','Developer','Accountant','Secretary');
CREATE TABLE employees (
employee_id int NOT NULL UNIQUE,
lastname text NOT NULL,
firstname text NOT NULL,
address text NOT NULL,
hire_date date NOT NULL,
salary numeric NOT NULL CHECK(salary > 1500),
emp_role emp_role,
department_id int NOT NULL
CONSTRAINT CK_employee CHECK (
NOT(
emp_role = 'Manager'
AND hire_date > DATE'2019-11-21'
AND salary > 15000
)
)
);
Demo on DB Fiddle
INSERT INTO employees VALUES(2,'foo','bar','foostreet','2019-12-20',180000,'Manager',3);
ERROR: new row for relation "employees" violates check constraint "ck_employee"
DETAIL: Failing row contains (2, foo, bar, foostreet, 2019-12-20, 180000, Manager, 3).
INSERT INTO employees VALUES(2,'foo','bar','foostreet','2019-12-20',1,'Developer',3);
ERROR: new row for relation "employees" violates check constraint "employees_salary_check"
DETAIL: Failing row contains (2, foo, bar, foostreet, 2019-12-20, 1, Developer, 3).

how to Implement a script that decomposes a sample database into two different databases?

I have this difficult question for my database subject. The exact question is
Implement SQL script solution3.sql that decomposes a sample database created by a script dbcreate.sql into the databases "NSW" and "VIC" located at the different Oracle servers.
The "NSW" database site supposed to contain information about the information of departments and employees located in the state NSW.
The "VIC" database supposed to contain information about the departments and
employees from the state of VIC.
what would the code look like to implement such a script? im a bit lost and confused.(i know how to connect to oracles im more lost on the script)
heres the code for the dbcreate. I believe what the question is asking is any instance of a record thats attatched to 'NSW' is copied to the NSW database and any instance of a record thats attatched to 'VIC" is copied to the VIC database
CREATE TABLE Department (
D# NUMBER(5) NOT NULL, /* Department number */
DName VARCHAR2(30) NOT NULL, /* Department name */
Manager# CHAR(5) NOT NULL, /* Department manager number */
MSDate DATE, /* Manager start date */
CONSTRAINT Department_PK PRIMARY KEY(D#),
CONSTRAINT Department_CK UNIQUE(DName)
);
CREATE TABLE DeptLocation (
D# NUMBER(5) NOT NULL, /* Department number */
Address VARCHAR2(50) NOT NULL, /* Department location */
CONSTRAINT DeptLocation_PK PRIMARY KEY(D#, Address),
CONSTRAINT DeptLocation_FK FOREIGN KEY(D#) REFERENCES Department(D#)
);
CREATE TABLE Employee (
E# CHAR(5) NOT NULL, /* Employee number */
Name VARCHAR2(30) NOT NULL, /* Employee name */
DOB Date, /* Date of birth */
Address VARCHAR2(50), /* Home address */
Sex CHAR, /* M-Male, F-Female */
Salary NUMBER(7,2), /* Salary */
Super# CHAR(5), /* Supervisor number */
D# NUMBER(5), /* Department number */
CONSTRAINT Employee_PK PRIMARY KEY(E#),
CONSTRAINT Employee_FK1 FOREIGN KEY (Super#) REFERENCES Employee(E#),
CONSTRAINT Employee_FK2 FOREIGN KEY (D#) REFERENCES Department (D#)
);
CREATE TABLE Project (
P# NUMBER(10) NOT NULL, /* Project number */
PTitle VARCHAR2(30) NOT NULL, /* Project title */
Sponsor VARCHAR2(30), /* Project sponsor name */
D# NUMBER(5) NOT NULL, /* Department number */
Budget NUMBER(10,2) NOT NULL, /* Project budget */
CONSTRAINT Project_PK PRIMARY KEY(P#),
CONSTRAINT Project_FK FOREIGN KEY (D#) REFERENCES Department(D#),
CONSTRAINT Project_CK UNIQUE (PTitle)
);
CREATE TABLE WorksOn (
E# CHAR(5) NOT NULL, /* Employee number */
P# NUMBER(10) NOT NULL, /* Project number */
Hours NUMBER(3,1) NOT NULL, /* Working hours per week */
CONSTRAINT WorksOn_PK PRIMARY KEY(E#, P#),
CONSTRAINT WorksOn_FK1 FOREIGN KEY(E#) REFERENCES Employee(E#),
CONSTRAINT WorksOn_FK2 FOREIGN KEY(P#) REFERENCES Project(P#)
);
CREATE TABLE Dependent (
E# CHAR(5) NOT NULL, /* Employee number */
DName VARCHAR2(30) NOT NULL, /* Dependent name */
Sex CHAR, /* Dependent sex, M-Male, F-Female */
DOB DATE, /* Date of birth */
Relationship VARCHAR2(10), /* Relationship with the employee */
CONSTRAINT Dependent_PK PRIMARY KEY(E#, DName),
CONSTRAINT Dependent_FK FOREIGN KEY(E#) REFERENCES Employee(E#),
CONSTRAINT Dependent_CK CHECK (Relationship IN ('SON', 'DAUGHTER', 'SPOUSE', 'OTHER'))
);
I have also set up the appropriate select statements. Change NSW for VIC if needed
/* NSW */
SELECT *
FROM DEPTLOCTAION
WHERE ADDRESS LIKE %NSW%;
SELECT *
FROM EMPLOYEE
WHERE ADDRESS LIKE %NSW%;
SELECT * FROM DEPARTMENT
JOIN EMPLOYEE ON DEPARTMENT.D# = EMPLOYEE.D#
WHERE ADDRESS LIKE '%NSW%';
SELECT * FROM PROJECT
JOIN EMPLOYEE ON PROJECT.D# = EMPLOYEE.D#
WHERE ADDRESS LIKE '%NSW%';
SELECT * FROM WORKSON
JOIN EMPLOYEE ON WORKSON.E# = EMPLOYEE.E#
WHERE ADDRESS LIKE '%NSW%';
SELECT * FROM DEPENDENT
JOIN EMPLOYEE ON DEPENDENT.E# = EMPLOYEE.E#
WHERE ADDRESS LIKE '%NSW%';
Are you restricted to using a SQL*Plus script? Are you allowed to create a database link? If both of these assumptions are true, here's a basic example of how I would tackle the problem.
CONNECT myschema/mypass#test
CREATE TABLE DeptLocation (
D# NUMBER(5) NOT NULL,
Address VARCHAR2(50) NOT NULL
);
INSERT INTO DeptLocation (
d#, address) VALUES (1, 'NSW');
INSERT INTO DeptLocation (
d#, address) VALUES (2, 'VIC');
COMMIT;
CONNECT myschema/mypass#dev
CREATE TABLE DeptLocation (
D# NUMBER(5) NOT NULL,
Address VARCHAR2(50) NOT NULL
);
CONNECT myschema/mypass#test
CREATE DATABASE LINK dev_dblink
CONNECT TO myschema IDENTIFIED BY mypass
USING 'dev';
INSERT INTO DeptLocation#dev_dblink (d#, address)
SELECT *
FROM DeptLocation
WHERE address LIKE '%VIC%';
DELETE
FROM DeptLocation
WHERE address LIKE '%NSW%';
COMMIT;

sqlite trigger checking equality of new tuple values with subqueries

I have a database representing a school with tables such as courses, students, and enrollment. They have the following schemas:
CREATE TABLE Students(
id INT CHECK(id > 100000),
lName CHAR(20),
fName CHAR(10),
gender CHAR(1) CHECK(gender IN('F','M')),
dob DATE,
address CHAR(100),
phone INT CHECK(phone > 1000000000),
grade CHAR(1) CHECK(grade IN('K','1','2','3','4','5')),
PRIMARY KEY(id));
CREATE TABLE Courses(
id INT CHECK(id > 1000),
name CHAR(40),
grade CHAR(1) CHECK(grade IN('K','1','2','3','4','5')),
PRIMARY KEY(id)
);
CREATE TABLE Enrollment(
studentID INT REFERENCES Students(id),
courseID INT REFERENCES Courses(id),
semester CHAR(6) CHECK(semester IN('Fall','Spring')),
year INT,
letterGrade CHAR(1) CHECK(letterGrade IN('A','B','C','D','E')),
PRIMARY KEY(studentID,courseID,semester,year));
I want to create a trigger for the enrollment table that will check that the grade level of the student with the given studentID and the grade level of the course with the courseID are equal before the tuple is inserted. I've been working on this for a while and can't seem to get it to work. Could anyone point me in the right direction?
This is what I've come up with:
CREATE TRIGGER appropriateLevel
...> BEFORE INSERT ON Enrollment
...> FOR EACH ROW
...> BEGIN
...> SELECT RAISE(ABORT,'The student's grade does not match the grade level of the course.')
...> WHERE EXISTS(SELECT * FROM Students, Courses WHERE ((Students.grade = Courses.grade) AND (Students.id = NEW.studentID) AND (Courses.id = NEW.courseID)));
...> END;
Thanks!
Your trigger aborts when the grades match.
Anyway, you don't need to use EXISTS because you want to compare only one specific value from each parent table:
CREATE TRIGGER appropriateLevel
BEFORE INSERT ON Enrollment
FOR EACH ROW
BEGIN
SELECT RAISE(ABORT, 'The student''s grade does not match the course''s grade level.')
WHERE (SELECT grade FROM Students WHERE id = NEW.studentID) <>
(SELECT grade FROM Courses WHERE id = NEW.courseID);
END;

Creating table with Identity related too other column in table

I'm trying to create a table that has a primary key (Department_ID) that auto assigns(not hard). However the assignment would be based on the exsisting value in another column(Department_Name). So for example if its the department_name payroll the department_ID would be 1 for example. If I tried to insert into and had to add another payroll employee it would not auto increment. It would assign value 1 to it. I assume its constraint I am looking for, but have no idea if I'm looking at this wrong or how to write it. Here's what I have so far:
CREATE TABLE tblDepartment
(
Department_ID int NOT NULL IDENTITY,
Department_Name varchar(255) NOT NULL,
Division_Name varchar(255) NOT NULL,
City varchar(255) default 'sometown' NOT NULL,
Building int default 1 NOT NULL,
Phone varchar(255) NOT NULL,
PRIMARY KEY (Department_ID)NOT NULL,
Check (Building >=1 AND Building <= 10 )
)
CREATE TABLE tblEmployee
(
Employee_ID int NOT NULL IDENTITY,
Department_ID int ,
Employee_Name varchar(255),
Social_Security_Number varchar(255),
Work_Phone varchar(255),
Position varchar(255),
Hire_Date datetime,
Birth_Date datetime,
FOREIGN KEY (Department_ID) REFERENCES tblDepartment(Department_ID)
)
Thanks for the help!
You shouldn't need a Department record per employee. You'll only have one Department record per department. You'll insert the Department.Department_ID value from the corresponding Department record into the Employee.Department_ID field when you insert an Employee record.
An autoincrement field for Department.Department_ID should be fine.
According to your schema, you already have a constraint that enforces this.
A TRIGGER on insert into tblEmployee that reads tblDepartment and sets the key accordingly might be a solution.
What happens if an employee changes department?