SQL statement for making foreign key - sql

ALTER TABLE Chosen_doctor ADD FOREIGN KEY (doctor)
REFERENCES Doctors (name) WHERE areaofexpertise LIKE `General%`
ON DELETE RESTRICT ON UPDATE RESTRICT;
Is this plausible sql statement i want to add to mz foreign key that it should onlz be referenced to doctors name if his area of expertise is general practitioner

FOREIGN KEYs are integrity constraints, not ways to achieve selections.
An FK has the side effect of creating INDEX, but that is for performance, not for filtering.
Filtering is achieved by using a WHERE clause in the SELECT statement.
Also, complex restrictions on DELETE and UPDATE must be handled via WHERE clauses.

In oracle you can create constraint like:
ALTER TABLE suppliers
ADD CONSTRAINT check_supplier_name
CHECK (supplier_name IN ('IBM', 'Microsoft', 'NVIDIA'));
But I didn’t see FK with ‘%like%’. I think in generally rdbms conception is not support FK with ‘like’. You also may create function for your case(task) and add this function in trigger on table before insert for each row .

Related

In Oracle, how would I begin to create the tables when all the needed tables have both foreign and primary key constraint?

In Oracle,
Lets say there are 3 tables with primary key and foreign key on each table. So, If i were to start creating the tables, how would i start. I started to create a first table with primary and foreign key but It don't let me create a table when there is foreign key mentioned without creating other referenced table.
if this the case, I can't create any of this tables, Because i foreign key on all 3 tables and primary on each table.
Note: Yeah, I know i could add the constraint later. but i'm curious to know, how does thing kind of issue work in real world programming. do developers add the foreign constraint later or ummmm just curious.
You can declare the foreign key constraint to be DEFERRABLE, which allows you to have Oracle check the constraint at the end of a transaction.
SET TRANSACTION;
SET CONSTRAINTS ALL DEFERRED;
INSERT INTO TABLE_ONE (PK1, FK2, NAME)
VALUES(10, 20, 'Foo');
INSERT INTO TABLE_TWO (PK2, FK3, NAME)
VALUES(20, 30, 'Bar');
INSERT INTO TABLE_THREE (PK3, FK1, NAME)
VALUES(30, 10, 'Baz');
COMMIT;
After each of the first two INSERTs, there is a foreign key with no referent, but Oracle won't check until the commit. After the third insert, everything is fixed.
Do you want this data structure though?
"Lets say there are 3 tables with primary key and foreign key on each
table. "
In the real world that couldn't happen. There must be at least one table which has no foreign key dependency on any other table.
In fact it's likely to be more complex than that. Most data models ave two sorts of tables: lookup (or code) tables and business data tables. There must be at least one business data table which doesn't depend on any other business data table, one which sits at the top of the tree.
"do developers add the foreign constraint later"
It depends. Generally speaking it is useful to have separate scripts for different sorts of DDL, so yes, it is common to create the tables in one pass, build indexes in another and add constraints afterwards. Such a strategy would be appropriate if the database phase includes data loading.
But if the delivered database will be empty - except for lookup data - the tables can be built in a singe script. In which case we need to order the script so that we build the tables without foreign key dependencies first, then build their children, then the grandchildren, and so on.

Should a foreign key be created on the parent table or child table?

What's the difference? If I have these two tables:
CREATE TABLE Account (Id int NOT NULL)
CREATE TABLE Customer (AccountId int NOT NULL)
And I want a foreign key linking the two, which of the following should I do and why?
Option 1:
ALTER TABLE [dbo].[Customer] WITH CHECK
ADD CONSTRAINT [FK_Accounts_Customers] FOREIGN KEY([AccountId])
REFERENCES [dbo].[Account] ([Id])
Option 2:
ALTER TABLE [dbo].[Account] WITH CHECK
ADD CONSTRAINT [FK_Accounts_Customers] FOREIGN KEY([Id])
REFERENCES [dbo].[Customer] ([Id])
Depends on context. Does every customer have a client? Which one is the parent? It seems like an Account has multiple Customers, in which case the reference belongs on the Customer table.
Now, that said, please call the entities CustomerID and AccountID everywhere. It may seem redundant on the primary table but the name should be consistent throughout the model.
I would use a foreign key from the child to the parent. The tell tale question is: what happens if you need to delete one of the entities?
A FK (foreign key) tells the DBMS that values for subrows for a column list must appear elsewhere as values for subrows for a column list. Whenever that happens (and it isn't already implied by other declartions) declare the FK. If in addtion you want a CASCADE action applied to the referenced table on a change to the referencing table, declare that.
(There's nothing special about CASCADE that it couldn't be offered for non-FK situations. It just comes up frequently with FKs, and there's an explicit graph of FKs by which to reasonably restrict their interactions.)
If there is a FK cycle then you will need to use triggers. Your decision of which constraint(s) are enforced declaratively & which by trigger should consider the graph of (desired) constraints.

SQL delete query with foreign key constraint

I know that this question belongs to the very early stages of the database theory, but I have not encountered such a problem since several months. If someone has a database with some tables associated together as "chain" with foreign keys and they want to delete a record from a table which has some "dependent" tables, what obstacles arise? In particular, in a database with tables: Person, Profile, Preference, Filter exist the associations as Person.id is foreign key in Profile and Profile.id is foreign key in Preference and Filter.id is foreign key in Preference, so as that all the associationsenter code here are OneToMany. Is it possible to delete a Person with a simple query:
Delete from Person p where p.id= 34;
If no, how should look like the query in order to perform the delete successfully?
If the database in the application is managed by hibernate, what constraints (annotations) should I apply to the associated fields of each entity, so as to be able with the above simple query to perform the delete?
FOR SQL VERSION
Look at the Screenshot. you can use the Insert Update Specificaiton Rules. as it has Delete and Update Rules. you can set either of these values.
Foreign key constraints may be created by referencing a primary or unique key. Foreign key constraints ensure the relational integrity of data in associated tables. A foreign key value may be NULL and indicates a particular record has no parent record. But if a value exists, then it is bound to have an associated value in a parent table. When applying update or delete operations on parent tables there may be different requirements about the effect on associated values in child tables. There are four available options in SQL Server 2005 and 2008 as follows:
No Action
Cascade
SET NULL
SET Default
Use this article for Refrence.
http://www.mssqltips.com/sqlservertip/2365/sql-server-foreign-key-update-and-delete-rules/
ORACLE VERSION
you can use one of below.
alter table sample1
add foreign key (col1)
references
sample (col2)
on delete no action;
alter table sample1
add foreign key (col1)
references
sample (col2)
on delete restrict;
alter table sample1
add foreign key (col1)
references sample (col2)
on delete cascade;
for refrance.
http://docs.oracle.com/cd/B19306_01/server.102/b14200/clauses002.htm
answer is no if there is foreign key constraint then you have to delete leaf node table data first
that is first delete from Preference table
then from Profile and Filter Table
then delete record from Person table
This is the generic concept that you apply anywhere

How to delete rows in associated SQL tables?

I want to delete rows in GlassesColor table that associated with GlassesID in Glasses table.
I want to implement this in stored procedure.The stored procedure gets only one parameter from client side , a CollectionID.
Here are the following tables:
Here is example of tables content:
Any idea how can i implement this?
Thank you in advance!
Manually deleting would be something like this:
delete
from GlassesColor
where GlassesID in (select GlassesID from Glasses where CollectionID = 3)
However, unless this is a one time cleanup, you should start specifying foreign key cascading rules, like the other answers already suggested.
The easiest way is to define FOREIGN KEYS with CASCADE options for DELETE.
http://msdn.microsoft.com/en-us/library/aa933119%28v=sql.80%29.aspx
I see you already have Foreign Keys defined, so you just need to make sure they have CASCADE option for DELETE.
Without stored procedure, use Constrains -> http://www.mssqlcity.com/Articles/General/using_constraints.htm OnDelete Cascade, so when you delete row in Glasses, it will deleted in Glasses color also.
In your foreign key constraint for the GlassesColor join table, have on delete cascade. What that means is when the primary key referenced record is deleted, the corresponding foreign key reference row will also be deleted.
So your GlassesColor table definition would look like this:
create table GlassesColor
(
GlassesId int foreign key references Glasses(GlassesID) on delete cascade,
.....
)
go
I answered something similar for using the INFORMATION_SCHEMA in MSSQL
SQL Server: drop table cascade equivalent?
Here's the easiest way to do it in Microsoft SQL Server: when you create the foreign key constraint, add ON UPDATE CASCADE ON DELETE CASCADE to its definition. I'm assuming you want changes to GlassesID to also propogate. ;-) If not, then you don't need the "ON UPDATE CASCADE".
Example:
ALTER TABLE
[GlassesColor]
WITH CHECK ADD CONSTRAINT
[FK_GlassesColor_GlassesID]
FOREIGN KEY
([glassesID]) REFERENCES [Glasses] ([glassesID])
ON UPDATE CASCADE ON DELETE CASCADE

Data Modeling: What is a good relational design when a table has several foreign key constrainst to a single table?

I have 2 tables:
1. Employees
2. Vouchers
Employees table has a single primary key.
Vouchers table has 3 foreign key constraints referencing the Employees table.
The following is a sample T-SQL script (not the actual table script) to create both tables and their relationship in SQL Server:
IF OBJECT_ID('dbo.Vouchers') IS NOT NULL
DROP TABLE dbo.Vouchers
IF OBJECT_ID('dbo.Employees') IS NOT NULL
DROP TABLE dbo.Employees
GO
CREATE TABLE Employees
(
ObjectID INT NOT NULL PRIMARY KEY IDENTITY
)
CREATE TABLE Vouchers
(
ObjectID INT NOT NULL PRIMARY KEY IDENTITY,
IssuedBy INT,
ReceivedBy INT,
ApprovedBy INT,
CONSTRAINT fk_Vouchers_Employees_IssuedBy FOREIGN KEY (IssuedBy)
REFERENCES Employees (ObjectID)
ON UPDATE CASCADE
ON DELETE NO ACTION,
CONSTRAINT fk_Vouchers_Employees_ReceivedBy FOREIGN KEY (ReceivedBy)
REFERENCES Employees (ObjectID)
ON UPDATE CASCADE
ON DELETE NO ACTION,
CONSTRAINT fk_Vouchers_Employees_ApprovedBy FOREIGN KEY (ApprovedBy)
REFERENCES Employees (ObjectID)
ON UPDATE CASCADE
ON DELETE NO ACTION
)
But an error is thrown:
Msg 1785, Level 16, State 0, Line 7
Introducing FOREIGN KEY constraint 'fk_Vouchers_Employees_ReceivedBy' on table 'Vouchers' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
I don't have an idea of what efficient solution is available here. The requirements on the relationship is that: whenever an Employee is deleted, the Voucher that references some of its columns to the Employee does not get deleted (ON DELETE CASCADE is not an option). Instead, the values of the columns (IssuedBy, ReceivedBy and/or ApprovedBy) that are referenced to the deleted Employee should be set to NULL (since the columns are NULLABLE).
Many thanks!
Strictly from a relational design point of view, the Vouchers table as three Foreign Keys. Whether you choose to enforce them, through CASCADE assertions or otherwise, is an implementation issue, but the relational design still exists. Presumably you want to enforce that, if one of the three fields is not NULL, then a matching record needs to exist. Or not. It's an implementation issue as to whether or not you care to enforce the design.
However, the violations you describe are assumed at your peril. The fact that you're asking this question suggests you may not fully appreciate all the ways these choices can lead into the swamp.
I think the error may be a consequence of the fact that more than one of the three might refer to the same employee.
BTW, I've in very few cases ever found it necessary to delete records in such a fashion that CASCADES are useful. Usually that would be used to prevent the database from being too big; and database capacity is less and less an issue over time.
I would not actually delete Employees, but instead use a trigger to set a flag to mark them as deleted.
I generally don't turn on cascade of Updates or Deletes, but instead require an application to explicitly perform these actions.
From a design standpoint it seems good to have the 3 foreign keys you listed. It looks like the error message you are getting relates to the ON UPDATE CASCADE options on your foreign keys (although I was able to create the table as specified). Regardless, to get the behavior you mention wanting, I would recommend a trigger on the Employees table, that fires before you delete the record. This trigger would find instances of the Employees.OjbectID in the Vouchers table and set them to NULL.