SQL: FOREIGN KEY prevents destruction of links between tables - sql

Refer: w3schools-SQL
It states:
The FOREIGN KEY constraint is used to prevent actions that would destroy links between tables. Can someone give an example of an action that foreign key would prevent ?
Thanks.

Lets say we have the two tables Employees and Departments. Each department has a unique number, and for each employee we list the number of the department that he or she works on. We have also declared this as a foreign key.
In that case the foreign key would prevent a number of actions:
Inserting a new employee who works on a department that doesn't exist
Deleting a department where there are employees who work
Updating an employee by changing the department he or she works on to a department that doesn't exist
Updating a department by changing its number, if there are employees who work on that department
Destroying the department table
All this is to ensure that when the database says that an employee works on a certain department, then that department will actually exist in the database.

Table Employee has its primary key set to empid.
Table Address references (foreign key constraint) empid in Table Employee
If you try deleting employee '1011' from Table Employee and that employee has a record in Table Address the delete will not go through because of the dependency. Unless you have cascading delete set up..

Table Users
ID UserName
1 msmucker0527
2 Jake
Table Email (Foreign Key: UserID = Users.ID)
UserID Email
1 msmucker0527#email.net
2 jake#email.net
You cannot add a record to the Email table with a UserID that does not exist in the Users Table. This way you don't have email addresses that are not "linked" to a User. You would also be prevented from deleting a user without first removing the email address so that it would not become stranded

Related

One-to-One relationship in database, foreign key should be in tableA or tableB?

Example scenario: 1 employee will only have 1 address and 1 address will only own by that 1 employee. Below are 2 options, which are correct or neither both?
More of my confusion is should I place Employee primary key into Address table or place Address primary key into Employee table?
I'm using PostgreSQL as some of you need to know which database am I using.
Option 1
Employee
EmployeeId (PK)
EmployeeName
AddressId (FK)
Address
AddressId (PK)
AddressLine1
Option 2
Employee
EmployeeId (PK)
EmployeeName
Address
AddressId (PK)
AddressLine1
EmployeeId (FK)
Does an employee have an address, or, does an address have an employee?
I would say, an employee has an address. I would think of employees as having a primary key, and employee attributes.
employee table:
employee id
employee attributes
...
Whether or not an address needs a primary key is another question. But, if you then want to give an employee an additional attribute, "address", which resides in a separate table, I would first think of adding the foreign key in the address table to indicate to which employee this address belongs:
address table:
employee id
address attributes
...
Note that now, an employee may have multiple addresses, but two employees cannot share the same address.
If you want multiple employees to share the same address, you could, for example, introduce a primary key in the address table, and use an intermediate table:
address table:
address id
address attributes
...
employee_address table:
employee id
address id
In this case, both fields in the employee_address table are foreign keys. It would not make sense that these would be primary keys. Here, I think you would agree, the primary keys are in the employee and address tables.
To your original question then, I would naturally put the employee primary key into the address table, to show that an address belongs to an employee. But, it might not be as simple as that. You have to consider the use cases, such as whether or not two employees share the same address, and whether or not employees can have multiple addresses. Or, could employees not have an address, or, could an address not have any employees?
You don't mention the specific database, so this answer assumes it implements constraint deferrability.
If you are absolutely sure the relationship is one to one, then one of the cleanest solutions is to share the primary key value and ensure you establish two symmetric foreign keys (from employee to address, and from address to employee).
Employee
EmployeeId (PK) (FK)
EmployeeName
Address
AddressId (PK) (FK)
AddressLine1
In order to insert, update, or modify data, both FKs must be made deferrable. Deferrablity is a standard SQL feature that I know at least PostgreSQL and Oracle implement.
If you want to go a step further, the name of the PK in the address table can be EmployeeId instead of AddressId, to emphasize it's one and the same.
For one to one relationship there is no reason to have multiple tables. Add address and AddressLine1 column into Employee table as below.
Employee
EmployeeId (PK)
EmployeeName
Address
AddressLine1
This will simplify your and ui design. And one to one relationship will be forced to be maintained without any constraint.

Understanding how Referential triggered actions work

I have this problem regarding 3 tables, that is in my database.
Employee, Pharmacist, and Medicine
Employee id is the primary key and it is referenced by the pharmacist table through a foreign key. This key is references as a foreign key by the medicine table which depicts the pharmacist who added the new medicine
The problem is face is this. When creating the foreign keys I have used on delete cascade, so when I delete an employee the relevant rows are deleted from both the employee and pharmacist table, but at the same time in the medicine table the medicine that was added by that particular employee too get deleted.
I have tried using on delete set default by giving a default value to the columns that are referenced through the foreign keys
The result i expect, is when i delete a particular employee that employees details must be deleted from both pharmacist and employee table, but in the medicine table the column that depicts which employee added this medicine must change to user unavailable or removed from system

Delete few records from table whose primary key referencing as foreign key in different table

For Example: I want to delete 2 records from Department table whose Dept_Id is primary key and this is referencing as Foreign key in Employee table. When I tried to delete, it gives error
The DELETE statement conflicted with the REFERENCE constraint
"FK__Employee__Dept_I__5CD6CB2B". The conflict occurred in database
"CRR_US_Report", table "dbo.Employee", column 'Dept_Id'.
You need to change the department IDs of the users in yours Employee table first. Then perform the delete from the Department table.
You have constraint that ensures that each user in the Employee table is having a valid department. You want to delete records from the Department table that are in use - so, you need to take care about the corresponding records in the Employee table first (delete, update, set to NULL if possible).
It is how foreign key works. So foreign key prevents deletion of record if this record is referenced in other tables and guarantees that your employee works in existing Department.
So you need edit IDs in Employee table which referenced by IDs which you want to delete from the Department table. And then delete Department field.
Am not sure, where you want delete the employees for dept that your are deleting
But first you can delete employee for the dept_id you want to delete then delete the dept_id
Delete from employee where dept_id=
Delete from dept where dept_id=
Hope this helps

update or delete on table "employee" violates foreign key constraint

I have an employee table with the following columns:
fname (varchar), lname (varchar), id (numeric)
id is the primary key.
There is a table name called works_on with columns
projectname (varchar), id (numeric)
Here, id is a foreign key that references the employee table.
When I was trying delete a row from the employee table like this:
delete from employee where id = 1
I get this error:
update or delete on table "employee" violates foreign key constraint "works_on_id_fkey" on table "works_on"`.
I am new to the database management system.
Any solution?
As employee is a foreign key in table works_on; the reason you are unable to delete employee ID 1 is because employee ID 1 exists on works_on (or perhaps other tables in which employee is a foreign key). The system is trying to maintain integrity of the database by preventing you from deleting an employee affiliated with works_on.
Say the system let you delete the employee record. Now when you look at the works_on table what would employee 1 relate to? You can no longer look up first/last names among other information. So the system is saying: If you want to delete the employee record, you must first remove/alter the foreign key associations to other system records; to ensure their continued integrity. If the system let you do this it would be called "Orphaning" a record. the parent record to which the child associates no longer exists.
To resolve a few options are:
Create a procedure that deletes employees but first checks any tables in which employee is a foreign key and ensures it's ok to delete those as well; and then deletes those records before deleting the employee record. (this can cause a massive daisy chain if those tables have PK's to which other tables are FK. But that's the nature of RDBMS.
Create a feature that lets you assign such records to employee 1's replacement or removes such records if no longer relevant.
enable ON DELETE CASCADE ON UPDATE CASCADE, which will automatically delete child records if parent record is deleted. (BE VERY CAREFUL AND CONSIDER how this impacts your system before enabling) Example: Docs
Don't delete the record, instead maintain a status field showing active/inactive and use it as a control mechanism to show or not show employees and their associated records.
There's several other options to consider as well; you must ask yourself, or the business for which this is being developed, what should happen to all those records in which employee 1 is a foreign key. Delete some/All, reassign some delete some? Prompt the user for how they want to handle each instance? Simply Inform the user they must first address the constraints found in (List all places this employee has a FK relationship?) and ensure they have a way to handle all those places... Lots of options.
You can not delete a row by that way. Because it has the constraint id in it (works_on_id_fkey). If you want to delete, you have to remove constraint from it.
alter table employee drop foreign key works_on_id_fkey

Updating an attribute to a foreign key

So I've currently got a database with a table named subject, within this is the name of the subject and the full name of the person responsible.
I've just added a new table with contact information, which has a primary key employee_id, and other attributes including employee_fn and employee_ln.
What I'm essentially trying to achieve, is to update the 'responsible' attribute from being the full name to being a foreign key referencing employee_id where the name corresponds accordingly.
I'm having trouble writing the SQL for this and honestly can't even work out how to do it manually nor with a query.
Any help is appreciated!
Thanks
From your question what i understand is you want to have responsible column as FK of Subject table and point it to the employee_id as FK ..right??
But that's not possible as FK needs to PK in other table. Employee_id will be an integer and will not be able to hold the full name.
Any sample data with expected output will help you out.
However if you have employee_id as a column in subject table then this update will work.
update subject s
set responsible = (
select employee_fn||employee_ln as fullname,employee_id
from
employee
) e
where e.employee_id = s.employee_id
your subject must have employee_id as fk and employee table as employee_id as PK for PK-FK relationship.