Problem using SQLite Trigger to increment a value - sql

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.

Related

How do you insert information in a table if you have a unary relationship

create table Employee(
staff_id_employee int primary key ,
gender char(1) check (gender in('F','M')),
staff_id int foreign key REFERENCES Staff(staff_id),
manager_id int foreign key references Employee(staff_id_employee)
);
How do I insert the information in this table.The text to this is that an employee manages other employees.If anyone could give me some sort of example cuz I don't know what to write instead of the question marks '????'.WHat is the value to manager_id in this case
INSERT into Employee(staff_id_employee, gender, staff_id, manager_id) VALUES (30000,'F',6007,????)
If you need to look-up the manager's Id then you want an insert select
INSERT into Employee(staff_id_employee, gender, staff_id, manager_id)
SELECT 30000,'F',6007, staff_id_employee
from Employee
where staff_id = [Manager's staff ID]
If Employee 3000 doesn't have a manager, you would typically insert a null
INSERT into Employee(staff_id_employee, gender, staff_id, manager_id)
VALUES (30000,'F',6007, null)
Otherwise insert the manager's ID.

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

Merge two tables with same primary key

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;

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?