Creating table with Identity related too other column in table - sql

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?

Related

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.

Foreign key missing parenthesis

CREATE TABLE EMPLOYEE (
EID CHAR(3) NOT NULL PRIMARY KEY,
ENAME VARCHAR2(50) NOT NULL,
JOB_TYPE VARCHAR2(50) NOT NULL,
MANAGER CHAR(3) FOREIGN KEY REFERENCES EMPLOYEE(EID),
HIRE_DATE DATE NOT NULL,
DNO INTEGER FOREIGN KEY REFERENCES DEPARTMENT(DNO),
COMMISSION DECIMAL(10,2),
SALARY DECIMAL(7,2) NOT NULL,
);
CREATE TABLE DEPARTMENT (
DNO INT NOT NULL PRIMARY KEY,
DNAME VARCHAR(50),
LOCATION VARCHAR(50) DEFAULT('NEW DELHI')
);
in creation of the employee table
this is giving me an error of right parenthesis
and the department table is already created
You have an extra comma in the line
SALARY DECIMAL(7,2) NOT NULL,
Delete that comma and the Employee table should be created.
You need to Create the Department Table first to use one of its
Columns as FOREIGN KEY.
Also, check your database. There might already be a Department Table. To avoid getting that error when the table needed is already created, use the keyword IF NOT EXISTS
CREATE TABLE IF NOT EXISTS Department(
DNO INT NOT NULL PRIMARY KEY,
DNAME VARCHAR(50),
LOCATION VARCHAR(50) DEFAULT('NEW DELHI')
);
The error is caused by the trailing comma, but you have other issues:
The FOREIGN KEY is not needed for an inline reference.
You need to define the tables in the right order.
So . . .
CREATE TABLE DEPARTMENT (
DNO INT NOT NULL PRIMARY KEY,
DNAME VARCHAR(50),
LOCATION VARCHAR(50) DEFAULT('NEW DELHI')
);
CREATE TABLE EMPLOYEE (
EID CHAR(3) NOT NULL PRIMARY KEY,
ENAME VARCHAR2(50) NOT NULL,
JOB_TYPE VARCHAR2(50) NOT NULL,
MANAGER CHAR(3) REFERENCES EMPLOYEE(EID),
HIRE_DATE DATE NOT NULL,
DNO INTEGER REFERENCES DEPARTMENT(DNO),
COMMISSION DECIMAL(10,2),
SALARY DECIMAL(7,2) NOT NULL
);
Here is an example of it working.

Cross Referencing Table Value for Another Value to allow Insert

How do I look at one table and use it to check another table for data integrity?
I have two SQL Tables.
One that is a person table
CREATE TABLE PERSON
(
ID INT IDENTITY(10000,1) NOT NULL,
Firstname VARCHAR(15),
Lastname VARCHAR(25) NOT NULL,
Birthdate DATE,
Gender VARCHAR(1),
CHECK ( GENDER IN ('M', 'F')),
Street VARCHAR(50),
City VARCHAR(15),
State VARCHAR(2),
CHECK (State IN ('FL','GA','PA')),
Zip INT,
Phone VARCHAR(10),
Employee VARCHAR(1),
CHECK ( Employee IN('Y','N')),
Member VARCHAR(1),
CHECK ( Member IN('Y','N')),
CHECK (Member IN ('Y') or Employee IN ('Y')),
CONSTRAINT PERSON_PK PRIMARY KEY (ID));
And Employee Table
CREATE TABLE EMPLOYEE
(
ID INT NOT NULL,
Datehired DATE DEFAULT GETDATE(),
Status VARCHAR(1),
CHECK ( Status IN ('F','C')),
Position VARCHAR(25),
EmpType VARCHAR(25),
CONSTRAINT EMPLOYEE_PK PRIMARY KEY (ID),
CONSTRAINT EMPLOYEE_PERSON_FK FOREIGN KEY (ID) REFERENCES PERSON);
Let's say someone isn't an employee. I can still insert them into the Employee Table.
INSERT INTO EMPLOYEE
(ID, Status, Position, EmpType)
VALUES
('10000','C','Teaching Classes','Instructor');
How Do I prevent this from happening.
One method is to have a redundant key:
alter table person
contraint unq_person_id_employee
unique (id, employee);
Then add a computed column to employee:
alter table employee add employee as ('Y') persisted;
Finally, add the constraint:
alter table employee
add constraint fk_employee_person
foreign key (id, employee) references person(id, employee);
Now, you are guaranteed that only employees are in the Employee table.

Constrain number of rows in table, by value in another table

I have a table called ward (dealing with hospitals):
Create table ward(
Wno varchar(15) Primary Key,
Name varchar(20) Not Null,
Number_of_beds integer Not Null
);
And a table for patients:
Create table patient(
Pid varchar(15) Primary Key,
Name varchar(20) Not Null,
Address varchar(50) Not Null,
Date_of_birth date Not Null
);
I need to constrain the patients somehow so that if a patient is assigned to a specific ward then the number of patients can't exceed the number of beds in the ward.
I thought of adding the Wno as a foreign key to the patient table, but don't really know where to go from there.
You may add the foreign key into patient table as following. Apology this query is in MYSQL. I noticed that you need Oracle though. However the logic is similar :) The syntax needs changes.
Create table ward(
Wno varchar(15) Not null Primary Key,
Name varchar(20) Not Null,
Number_of_beds integer Not Null
);
And a table for patients:
Create table patient(
Pid varchar(15) Primary Key,
Name varchar(20) Not Null,
Address varchar(50) Not Null,
Date_of_birth date Not Null,
WardNo varchar(15),
foreign key (wardno) references ward (wno) ' -- adds the foreign key relation
);
In order to check if ward is full, you can have an insert or update trigger
Free bed count can be obtained by following query:
SELECT p.wardno, (w.number_of_beds - count(pid)) as freebeds
from patient as p
left join ward as w
on p.wardno = w.wno
group by wardno
Now we create a trigger to check if any patient is going into a ward whre freebed count = 0.
Updated to Oracle Version
CREATE OR REPLACE TRIGGER FreeBedsWardTrigger
BEFORE UPDATE OR INSERT
ON patient
FOR EACH ROW
DECLARE
max_beds INTEGER; -- max number of beds for the ward
used_beds INTEGER; -- used beds for the ward
BEGIN
SELECT COUNT (pid)
INTO used_beds
FROM patient
WHERE wardno = :NEW.wardno;
SELECT number_of_beds
INTO max_beds
FROM ward
WHERE wno = :NEW.wardno;
IF (max_beds - used_beds) > 0
THEN
RETURN;
ELSE
RAISE_APPLICATION_ERROR (-100100,
'No more beds available in this ward.');
END IF;
END;

ORA-00900: invalid SQL statement

CREATE TABLE Customers(
CustID number(5,0),
EmpID CHAR(1),
Cust_Name varchar(20) not null,
Cust_Address varchar(20) not null,
Cust_City varchar(20) not null,
Cust_State char(2) not null,
Cust_Zipcode number(5,0) not null,
Ship_Date date not null,
Order_Date date not null,
constraint ci_fk FOREIGN KEY (EmpID) references EMPLOYEES(EmpID),
constraint ci_ck check (Ship_Date>Order_Date)
)
What's the problem?
Employees table does not exist.
or EmpId is not a primary key.
Once I did these, my copy of the create statement worked.
Chris said it.
Change CHAR to VARCHAR2 as CHAR should never be used. Also, number(5,0) is the same as NUMBER(5), so you can use that.
Verify that the Employees table exists.
Verify that the EmpID column in the Employees table is of the same datatype as in the Customers table.
Verify that the EmpID column in the Employees table is the primary key of the employee table.