Understanding how Referential triggered actions work - sql

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

Related

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

Query regarding SQLite and Cascading foreign keys

I am currently writing a application in C# that uses a SQLite database to store information the user will input. The application is basically a Management system for users who are called "Students" in the application. This is the most important table in my database and every other table is linked off this table. What I want to do is when a student is removed - they leave the institute/get kicked out etc. - is to remove their data from all the other tables so that data is no longer there as it isn't needed. An example of some of the Create table statements I have written is:
CREATE TABLE student(studentID int(5) PRIMARY KEY NOT NULL, name string(16),...,DOB string(8) );
CREATE TABLE emergencyContact(emergencyID int(5) PRIMARY KEY NOT NULL, name string(16),..., contactNumber int(16));
CREATE TABLE emergencyContactOf(studentID int(5) FOREIGN KEY REFERENCES student('studentID'), emergencyID int(5) FOREIGN KEY REFERENCES emergencyContact('emergencyID');
I have read up on this and my understanding is the data will be deleted in the EmergencyContactOf table if I include a 'ON DELETE CASCADE' statement as the StudentID key will no longer be present in the Parent table.
However, my understanding is the data in the EmergencyContact table that is for that specific student will not be deleted as there is no reference to the StudentID.
My question is, is there a way to remove the data from this table also that is relevant to that Student? For example, if I was to include a column in the EmergencyContact table which would reference the StudentID as a Foreign Key and then remove that row if the StudentID is ever deleted from the parent table? Is this a good solution to this particular problem?
All other tables I have are also designed in this way, where the data is in different tables and then linked back to the Student table with relationship tables so this will also apply to all the other tables I have.
Thanks.
My question is, is there a way to remove the data from this table also that is relevant to that Student? For example, if I was to include a column in the EmergencyContact table which would reference the StudentID as a Foreign Key and then remove that row if the StudentID is ever deleted from the parent table? Is this a good solution to this particular problem?
What happens if multiple students have the same emergency contact? You don't want to duplicate data if you don't have to - that's the whole point of the emergencyContactOf table, to efficiently set up a many to many relation between students and emergency contacts. So you don't want to do something like you describe.
You could periodically (Monthly, yearly, after purging student rosters, whatever) run a delete that removes rows from emergencyContact if they don't appear in emergencyContactOf:
DELETE FROM emergencyContact
WHERE emergencyID NOT IN (SELECT emergencyID FROM emergencyContactOf)
or the like.
Hmm, I see two scenarios here. What if two students have the same emergency contact, say two bothers having their father as emergency contact?
If in such a case you store only one record (the father) in the emergency contact table, you don't want to delete the emergency contact if only one of them leaves. You'd delete the emergency contact for the other one. So you'd need additional logic, when to delete an emergency contact. You could put that in a trigger.
You use a less sophisticated approach and multiple rows from the emergency contact table can map to one person in real life. In that case you can pull the reference to the student directly into the emergency contact table and use ON DELETE CASCADE there.
CREATE TABLE student
(studentid int(5),
name string(16),
...
PRIMARY KEY (studentid),
...);
...
CREATE TABLE emergencycontact
(emergencycontactid int(5),
studentid int(5),
name string(16),
...
PRIMARY KEY (emergencycontactid),
FOREIGN KEY (studentid)
REFERENCES student
(studentid),
...);
The second might be tempting but the "clean way" is the first one, as the second allows contradicting data. From what you posted you're already on the "clean way". But a mentioned that required triggers.

SQL JDBC: parent key not found BUT the parent values have already been inserted into the database

I'm having a problem inserting mock data into the database
The table I'm trying to insert the values into is called 'purchased'
which has some foreign key values such as patient_id, pharmacy_id, drug_id.
The other 3 tables 'patient', 'pharmacy', 'drug' have already been added to the database successfully.
Patient table has a foreign key which is doctor_id. The 'doctor' table has also been added to the database.
Since I know that a foreign key patient_id in 'purchased' table depends upon another foreign key doctod_id, so I've done something like this
foreign key (patient_id, receipt_no) references patient(patient_id,doctor_id) ON DELETE CASCADE
Not sure what I've missed here, why does sqlplus complain that the parent key is not found? Just working for a database class project so I'm still learning.
Here's .sql code file
https://gist.github.com/mopkaloppt/de8fbf64c4d5711c90e2b389a72911ba
Any kind of help will be much appreciated.. I'm freaking out a bit now as I've been struggling with this for a while and it's due soon :(
This part of your FK constraint looks confused:
foreign key (patient_id, receipt_no) references patient(patient_id,doctor_id) ON DELETE CASCADE
^^^^^^^^^^ ^^^^^^^^^
You are getting the errors because there is no receipt_no in your purchased data that matches a doctor_id. This is perhaps unsurprising as the data are unrelated.
Having looked at the data in your patient table, it seems you haven't got the database design quite right. There's duplication in that table: if a patient has multiple illnesses or sees multiple doctors then there are repeated values for all other columns. This is also getting in the way of your FK constraint: you are trying to link a row in purchased to a patient, but there are multiple rows for some patients, so which row do you link to?
It seems you have a many-to-many relationship between patients and illnesses (a patient can have multiple illnesses, multiple patients can have an illness), and also between patients and doctors (a patient can be seen by multiple doctors, a doctor can see multiple patients). So, I would recommend introducing new tables for the relationships between patients and illnesses, and between patients and doctors. For example, here's the table you could use for the relationship between patients and doctors. Insert one row into this table for each combination of patient and doctor:
create table patient_doctor (
patient_id char(4) not null,
doctor_id char (4) not null,
primary key (patient_id, doctor_id),
foreign key (patient_id) references patient(patient_id) on delete cascade,
foreign key (doctor_id) references doctor(doctor_id) on delete cascade);
A linking table such as this is the standard way of representing a many-to-many connection in a relational database.
You don't yet have a table for illnesses, so I'll leave you to create a table for them, a linking table similar to that for patients and doctors (patient_illness perhaps), and the data in both tables.
Once you've done that, remove the doctor_id and illness columns from patient, remove the duplicate rows and make the patient PK depend only on patient. Your FK constraint from purchased to patient can then reference only patient_id.
Hopefully after doing all of this you should see your FK constraint violation errors go away.

SQL: FOREIGN KEY prevents destruction of links between tables

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