The foreign key constraint - sql-server

I have a table which contained the following columns.
ID int PK
Name nvarchar(50) NotNull
FID int FK reference to ID
ID Name PK
1 A Null
2 B Null
3 C 1
4 D 1
5 E 1
6 F 2
So, The primary key includes as a primary key in a table. I want to do that if the primary key is deleted, the rows which is contained the primary key as a foreign is deleted automatically. (example: When I delete ID 1 row, I want to delete automatically ID 3, 4, 5 rows.). How to make that the primary key is included as a foreign key in a table? How can I do this. Thanks.

You need to implement a "trigger" that does a "cascading delete".
Here's a good link:
http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=142564
CREATE TRIGGER test_trig
ON dbo.Table_1
FOR DELETE
AS
BEGIN
delete a from dbo.Table_2 a
JOIN
deleted d
ON a.joincol = d.joincol
END
Here are some other alternatives:
http://www.mssqltips.com/sqlservertip/1508/foreign-key-vs-trigger-referential-integrity-in-sql-server/
And here is a link to Microsoft's documentation on "Cascading Referential Integrity Constraints":
http://msdn.microsoft.com/en-us/library/ms186973.aspx

NOTE: In Microsoft SQL, a cascading delete to a self-referencing table is not allowed. You must either use a trigger, create a stored procedure, or handle the cascading delete from the calling application. An example of this is where a single table has an ID as identity and a ParentID with a relationship to ID in the same table.
see here

The only way will be to add a trigger you can refer the following links for more information.
http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataproviders/thread/b777ec73-e168-4153-a669-835049a96520
another link

Related

Unique constraint including field in referenced table

Is is possible to add a uniqueness constraint to a table that would include a field from a referenced table? If so, how can that be done?
(Note that I'm using Microsoft SQL Server.)
To explain why this is necessary, here's a simplified version of my problem.
Firstly, let's say I have a table of things, defining the fixed properties of each individual thing:
CREATE TABLE dbo.things(
id INT IDENTITY(1,1) NOT NULL
CONSTRAINT [things$PrimaryKey] PRIMARY KEY CLUSTERED,
thing_name NVARCHAR(20) NOT NULL
CONSTRAINT [things$thing_name] UNIQUE,
-- etc.
);
I also have different configurations, for a range of different elements, not just things, and these are captured in a table too:
CREATE TABLE dbo.configurations(
id INT IDENTITY(1,1) NOT NULL
CONSTRAINT [configurations$PrimaryKey] PRIMARY KEY CLUSTERED,
config_name NVARCHAR(20) NOT NULL
CONSTRAINT [configurations$config_name] UNIQUE,
-- etc.
);
I then want to have different configurations for each thing:
CREATE TABLE dbo.thing_configurations(
id INT IDENTITY(1,1) NOT NULL
CONSTRAINT [thing_configurations$PrimaryKey] PRIMARY KEY CLUSTERED,
thing_id INT NOT NULL
CONSTRAINT [thing_configurations$things_fk] REFERENCES dbo.things(id),
quantity INT NOT NULL
CONSTRAINT [thing_configurations$quantity] CHECK(quantity >= 0),
-- etc.
);
Next, I want to identify the configuration of each thing for each particular configuration in an association table. I can ensure that the configuration and associated thing configuration are unique, but I want to ensure that each thing has no more than one thing configuration for each configuration.
CREATE TABLE dbo.config_thing_configurations(
config_id INT NOT NULL
CONSTRAINT [config_thing_configurations$configurations_fk] REFERENCES dbo.configurations(id),
thing_config_id INT NOT NULL
CONSTRAINT [config_thing_configurations$thing_configurations_fk] REFERENCES dbo.thing_configurations(id)
-- How can I ensure that I do not have multiple configurations of a each thing in a configuration.
);
More specifically, say I have these things:
id
thing_name
1
Apple
2
Bicycle
...
...
And these configurations:
id
config_name
1
Base configuration.
2
Experiment #1
...
...
And these thing configurations:
id
thing_id
quantity
1
1 (Apple)
20
2
1 (Apple)
30
3
2 (Bicycle)
5
...
...
How can I prevent each configuration from having two or more different configurations of each individual thing in the thing_configurations table?
config_id
thing_config_id
1
1 (20 Apples)
1
2 (30 Apples)
...
...
For example, in the above table, I have two conflicting configurations for Apples in configuration 1.
Ideally, I'd like to be able to enforce a uniqueness constraint for config_id and the thing_id referenced through the thing_config_id. Is that possible?
So this is possible, through the creation of an indexed view in combination with a unique index.
In this specific example, this is achieved by first creating a view that associates the configuration and thing identifiers:
CREATE VIEW dbo.thing_config_view WITH SCHEMABINDING AS
SELECT
thing_configurations.thing_id,
config_thing_configurations.config_id
FROM dbo.config_thing_configurations
INNER JOIN dbo.thing_configurations ON config_thing_configurations.thing_config_id = thing_configurations.id;
Next, we create a unique index on those fields from the view:
CREATE UNIQUE CLUSTERED INDEX [thing_config_view$unique_thing_configurations] ON dbo.thing_config_view(thing_id, config_id);
and it works exactly as required.
This could be handled through Triggers. The trigger content would depend on what you want to occur when a query is called that would violate the condition. Something like this for insert (untested):
CREATE TRIGGER tr_config_thing_configurations ON config_thing_configurations
INSTEAD OF INSERT
AS
IF EXISTS(
SELECT 1
FROM inserted i
INNER JOIN thing_configurations tc ON tc.id = i.thing_config_id
INNER JOIN things t ON t.id = tc.thing_id
WHERE t.id IN (
SELECT it.id
FROM config_thing_configurations ictc
INNER JOIN thing_configurations itc ON itc.id = ictc.thing_config_id
INNER JOIN things it ON it.id = itc.thing_id
WHERE
ictc.config_id = i.config_id
)
BEGIN
RAISERROR ('Configuration already has a configuration for thing', 16, 1);
ROLLBACK TRANSACTION;
RETURN
END
INSERT INTO config_thing_configurations (config_id, thing_config_id) SELECT config_id, thing_config_id FROM inserted;
GO
You would need another for update or you could write a single to handle both cases.

Sql condition with two foriegn key columns

I'm new to sql and
have a table dbo.Student
**column** **datatype**
Student Id Primary Key int not null
ClassId Foriegn Key int not null
BaseId Foriegn Key int not null
ClassId can have multiple base Id but not duplicates
I'm looking to write a condition If any ClassId have duplicate rows with same BaseId's
Example for good data
a b c
1 2 1
2 2 2
Example for bad data
a b c
1 2 1
2 2 1
Thanks
You can use below query to check if you have any duplicate rows in the table
select ClassId,baseid, COUNT(*) NumberOfDuplicate
from student
group by ClassId,baseid
having count(*) >1
There are "unique" constraints in SQL server. You can add one to that column and it will prevent the entry of a row in which that column value is not unique. Unique constraints are allowed on columns that are not keys.
This SO answer has both the gui solution and script solution:
stackoverflow.com/questions/5181877/
Gist of linked answer:
ALTER TABLE TableName ADD CONSTRAINT ConstraintName UNIQUE(ColumnName1, ColumnName2)
This will put a unique constraint on the combination of Column1 and Column2.
In SSMS object Explorer if you expand the table and look under "Keys" to see your constraint.
GUI steps:
Open SQL Server Management Studio.
Expand the Tables folder of the database where you want to create the
constraint.
Right-click the table where you want to add the constraint and click Design.
In the Table Designer menu, click Indexes/Keys.
In the Indexes/Keys dialog box, click Add.
Choose Unique Key in the Type drop-down list.

Implementing foreign key from two different tables

I have three tables and from first table I want to send data column transId into second table column refId, and the same from third table I want to send data column transId into second table column refId with relation of both first and third table. How is this possible?
We can create Multiple Foreign Key On Same Column, but each of those would require the value to exist.
Eg:
Table1(1,2,3)
Table2(3,4)
You can insert the value 3 to the table3 column that have the foreign key relation to both table1 and table2(value 3 exists in both table1 and table2), but you can't insert any other values.
There is one more method to solve this, you can use an User Defined Function inside a Check constraint of table3 column to check the value exists or not in the table1 and table2
You don't need to send data from table to other. you only need to make reference from foreign_key_column (refId) to Primary_key_column (transId).
As example:
Using SQL Server
// foreign key in second table
CREATE TABLE Table2
(
refId int FOREIGN KEY REFERENCES Table1(transId)
)
// foreign key in third table
CREATE TABLE Table3
(
refId int FOREIGN KEY REFERENCES Table1(transId)
)
helped Tutorial
Seems Table2 is the master table containing column transId which references to two tables table 1 and table 2.You need to go with the creation of foreign key in table 2 and table 3 for column transId.You can use below syntax for creating relationship among tables:
--foreign key in First table
CREATE TABLE Table1
(
refId int FOREIGN KEY REFERENCES Table2(transId)
)
-- foreign key in third table
CREATE TABLE Table3
(
refId int FOREIGN KEY REFERENCES Table2(transId)
)

Is it equivalent to add a foreign key to an already existent table's already existent field with already existent records than recreation?

I have three tables: A, AB and B.
A.ID and B.ID are int primary keys. AB.AID and AB.BID are int and (AID, BID) is the primary key of AB.
I need to make sure that AB.AID will be a foreign key which will reference A(ID) and AB.BID will be a foreign key which will reference B(ID).
If I, using Microsoft SQL Server Management Studio right-click the table and click Design and after the table appears I right-click and click on Relationships and add the foreign key, will I have the very same result as if I would:
Create a temporary table with the same structure
Migrate all records from AB there
Remove all records from AB
Change the structure of AB to have two foreign keys
Copy the data back
Remove the temporary table
?
There is no difference. Note that when attempting to build a relationship between tables, it will not allow the constraint to be created if there is conflicting data like:
Tbl1 (tbl1_id PK)
-----
1
2
Tbl2 (tbl2_id PK, tbl1_id)
-----
1
2
3
if you tried to create the foreign key, it would face as 3 does not exist within your primary table.
So yes, they are equivalent, just note that SQL server has built in safe guards to protect against invalid relational data.

Do Foreign Key constraints get checked on an SQL update statement that doesn't update the columns with the Constraint?

Do Foreign Key constraints get checked on an SQL update statement that doesn't update the columns with the Constraint? (In MS SQL Server)
Say I have a couple of tables with the following columns:
OrderItems
- OrderItemID
- OrderItemTypeID (FK to a OrderItemTypeID column on another table called OrderItemTypes)
- ItemName
If I just update
update [dbo].[OrderItems]
set [ItemName] = 'Product 3'
where [OrderItemID] = 2508
Will the FK constraint do it's lookup/check with the update statement above? (even thought the update is not change the value of that column?)
No, the foreign key is not checked. This is pretty easy to see by examining the execution plans of two different updates.
create table a (
id int primary key
)
create table b (
id int,
fkid int
)
alter table b add foreign key (fkid) references a(id)
insert into a values (1)
insert into a values (2)
insert into b values (5,1) -- Seek on table a's PK
update b set id = 6 where id = 5 -- No seek on table a's PK
update b set fkid = 2 where id = 6 -- Seek on table a's PK
drop table b
drop table a
No. Since the SQL update isn't updating a column containing a constraint, what exactly would SQL Server be checking in this case? This is similar to asking, "does an insert trigger get fired if I only do an update?" Answer is no.
There is a case when the FK not existing will prevent updates to other columns even though the FK is not changed and that is when the FK is created WITH NOCHECK and thus not checked at the time of creation. Per Books Online:
If you do not want to verify new CHECK or FOREIGN KEY constraints
against existing data, use WITH NOCHECK. We do not recommend doing
this, except in rare cases. The new constraint will be evaluated in
all later data updates. Any constraint violations that are suppressed
by WITH NOCHECK when the constraint is added may cause future updates
to fail if they update rows with data that does not comply with the
constraint.

Resources