Define an SQL constraint depending on more than one attribute - sql

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

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.

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.

Database Design in PostgreSQL

I am designing a database for school.
Requirements
Professors have an SSN, a name, an age, gender, a rank, and a research specialty
Professors work in exactly one department
Departments have a department number, a department name, and a main office
Departments must have one professor (known as the chairman) who runs the department
My current schema for "Professors" and "Departments"
CREATE DOMAIN SSN AS CHAR(11) CONSTRAINT validSSN CHECK (VALUE ~* "^\d{3}-\d{2}-\d{4}$");
CREATE TABLE Persons (
person_id INT PRIMARY KEY AUTO_INCREMENT,
ssn SSN NOT NULL CONSTRAINT mustBeDifferent UNIQUE,
name VARCHAR(255) NOT NULL,
age INT NOT NULL CONSTRAINT nonnegativeAge CHECK(age >= 0),
gender CHAR(1) CONSTRAINT mustBeMaleOrFemale CHECK(gender = "M" OR gender = "F") NOT NULL,
);
CREATE TABLE Professors (
ranking INT NOT NULL CONSTRAINT positiveRanking CHECK(ranking > 0),
research_specialty VARCHAR(255) NOT NULL,
department_id INT NOT NULL REFERENCES Departments(department_number)
) INHERITS(Persons);
CREATE TABLE Departments (
department_number INT PRIMARY KEY AUTO_INCREMENT,
department_name VARCHAR(255) NOT NULL,
main_office VARCHAR(255) NOT NULL,
chairman_id INT REFERENCES Professors(person_id)
);
I have a foreign key in the "Professors" table that references the "Departments" table and a foreign key in the "Departments" table that references the "Professors" table.
Is there any way that I could go about resolving this issue?
I see a few problems:
professors should not inherit from persons, but reference it with a foreign key.
Otherwise you cannot guarantee uniqueness of the primary key.
Don't store the age in persons, but the birthday.
Otherwise your data will grow invalid pretty quickly.
If there is no length limit dictated by the application, don't use varchar(255), but use text.

Check Constraint Violated Error, But Column Unspecified

I've made the following table below:
CREATE TABLE Employee (
Employee_ID NUMBER(10) NOT NULL PRIMARY KEY,
Company_ID NUMBER(10) NOT NULL REFERENCES
Penrhyn_Jet_Charter(Company_ID),
First_Name VARCHAR2(255) NOT NULL,
Last_Name VARCHAR2(255) NOT NULL,
Address VARCHAR2(300) NOT NULL,
Email_Address VARCHAR2(255) NOT NULL UNIQUE CHECK (Email_Address
LIKE '%_#__%.__%'),
Telephone_Number NUMBER(15) NOT NULL CHECK (Telephone_Number > 0),
Mobile_Number NUMBER(15) NOT NULL UNIQUE CHECK (Mobile_Number>0),
Date_Of_Birth DATE NOT NULL,
Gender CHAR(1) NOT NULL, CHECK (Gender = 'M' OR Gender
= 'F'),
NI_Number VARCHAR2(10) NOT NULL UNIQUE CHECK (NI_Number Like
'[a-z][a-z][0-9][0-9][0-9][0-9][0-9][0-9][a-z]'),
Job_Description VARCHAR2(255) NOT NULL,
Annual_Salary NUMBER(10) NOT NULL CHECK (Annual_Salary > 0)
);
CREATE OR REPLACE TRIGGER Check_Date_Of_Birth
BEFORE INSERT OR UPDATE ON Employee
FOR EACH ROW
BEGIN
IF( :NEW.Date_Of_Birth < DATE '1900-01-01' OR
:NEW.Date_Of_Birth > SYSDATE )
THEN
RAISE_APPLICATION_ERROR ( -20001,
'Date of birth must be later than Jan 1, 1900 and earlier than today'
);
END IF;
END;
The above table was created with no errors.
But when I'm trying to populate the table, It's gives me this error:
INSERT INTO Employee VALUES (1, 1, 'Gary', 'Turner', '5 Orpington Street, Crawley, CR18 25J',
'garyturner#mail.com', 087948743, 938468364, TO_DATE('1985-05-06','YYYY-MM-DD'),
'F', 'aa111111a', 'Pilot', 12500)
Error report -
ORA-02290: check constraint (K1651915.SYS_C0074079) violated
This is my insert statement:
INSERT INTO Employee VALUES (1, 1, 'Gary', 'Turner', '5 Orpington
Street, Crawley, CR18 25J',
'garyturner#mail.com', 087948743, 938468364, TO_DATE('1985-05-
06','YYYY-
MM-DD'),
'F', 'aa111111a', 'Pilot', 12500);
It doesn't specify which column's check constraint it violates, so I'm confused.
What am I doing wrong and how can I fix it?
In short, your CHECK CONSTRAINT uses a REGEXP check, but is actually expecting a WHERE check.
If you want to use regular expressions inside your check constraint, you'll need to use REGEXP_LIKE:
CONSTRAINT ck_ni_number
CHECK (REGEXP_LIKE(ni_number, '[a-z][a-z][0-9][0-9][0-9][0-9][0-9][0-9][a-z]'))
This code would go at the end of your CREATE TABLE statement. I've declared it this way (caleld and out-of-line constraint) as it allows you to name the constraint and easily see the error will relate to ni_number.
Your entire CREATE TABLE statement would then look like this:
CREATE TABLE Employee (
Employee_ID NUMBER(10) NOT NULL PRIMARY KEY,
Company_ID NUMBER(10) NOT NULL REFERENCES Penrhyn_Jet_Charter(Company_ID),
First_Name VARCHAR2(255) NOT NULL,
Last_Name VARCHAR2(255) NOT NULL,
Address VARCHAR2(300) NOT NULL,
Email_Address VARCHAR2(255) NOT NULL UNIQUE,
Telephone_Number NUMBER(15) NOT NULL,
Mobile_Number NUMBER(15) NOT NULL UNIQUE,
Date_Of_Birth DATE NOT NULL,
Gender CHAR(1) NOT NULL,
NI_Number VARCHAR2(10) NOT NULL UNIQUE,
Job_Description VARCHAR2(255) NOT NULL,
Annual_Salary NUMBER(10) NOT NULL,
CONSTRAINT ck_ni_number
CHECK (REGEXP_LIKE(ni_number, '[a-z][a-z][0-9][0-9][0-9][0-9][0-9][0-9][a-z]')),
CONSTRAINT ck_tel_num CHECK (Telephone_Number > 0),
CONSTRAINT ck_email CHECK (Email_Address LIKE '%_#__%.__%'),
CONSTRAINT ck_mob_num CHECK (Mobile_Number > 0),
CONSTRAINT ck_gender CHECK (Gender = 'M' OR Gender = 'F'),
CONSTRAINT ck_an_salary CHECK (Annual_Salary > 0)
);
Also, I would suggest specifying the columns in your INSERT statement. Without the column names specified, Oracle will assume an order of your values, which is not guaranteed.
To do this:
INSERT INTO Employee
(employee_id, company_id, first_name, last_name, address,
email_address, telephone_number, mobile_number, date_of_birth,
gender, ni_number, job_description, annual_salary)
VALUES (1, 1, 'Gary', 'Turner',
'5 Orpington Street, Crawley, CR18 25J',
'garyturner#mail.com', 087948743, 938468364,
TO_DATE('1985-05-06','YYYY-MM-DD'),
'F', 'aa111111a', 'Pilot', 12500);
One other suggestion I would make is that you may want to consider making the phone_number and mobile_number fields VARCHAR2 instead of numeric. This is because phone numbers may start with 0, and phone numbers don't have any arithmetic performed on them. But that's outside the scope of your question!
Hope that resolves your issue.

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?