Create SQL one-to-many relationship with itself - sql

I'm trying to create a one-to-many relationship on a table A with it's own records.
I thought I could just create a second table B, with two foreign keys linking to table A. It appears that this is not sufficient, as LINQ-to-SQL generated a one-to-one relationship. What am I missing?
Some context: table A contains tags, and tags can be sub tags of tags.
Edit: Maybe I need a many-to-many relationship?

Assuming you have a table with the following columns itemid and MasterID
in the column masterid you have the itemid of the item it links to
select a.Itemid,b.itemid from table1 as a inner join table1 as b on a.Itemid=b.MasterID
Above query will give you a result like this :
a_itemid b_itemid
3020079 3020334
3020079 3020335
3045396 3045397
3045396 3045398
3045396 3045401
3020079 3577149

SQL server won't let you create a foreign key for the table referencing itself with ON DELETE CASCADE or ON UPDATE CASCADE since it may cause cycles or multiple cascade paths. But you can create foreign key with ON DELETE NO ACTION and ON UPDATE NO ACTION.
ALTER TABLE tagtablename ADD FOREIGN KEY ([parent_id]) REFERENCES [tagtablename] ([id]) ON DELETE NO ACTION ON UPDATE NO ACTION

You also need to make the two keys in your link table B, the primary key of this table.
Also, Linq2SQL seems to generate properties based on the names of your keys. This resulted in some odd names for me.

Related

How to delete records from two different tables that are linked with FK? SQL

I have two tables City and Buildings in my database. They are linked with city_number that is Primary Key in City table and Foreign Key in Buildings table. If user wants to delete record from City table I want to remove any records from the Buildings table that is tied to that City. I use unique auto incremented id passed through the argument to remove these records. My SQL Query looks like this:
DELETE C.*, B.*
FROM City AS C
INNER JOIN Buildings AS B
ON C.c_number = B.b_district
WHERE D.c_id = 'some id example: 107';
Query above won't work sicne SQL allow only records from one table to be removed with INNER JOIN so i will have to use two separate DELETE statements like this:
DELETE
FROM City
WHERE c_id = '107'
DELETE
FROM Buildings
WHERE b_city = 'city that is tied to unique id 107'
My question is, what is the best practice to remove records that are tied in two tables? Since I have to use two separate SQL statements, should I pass City and then delete record(s) from Buildings table? or Should I create another query that will pull City from City table based on unique id and then remove record(s) from Buildings? If anyone knows better way to do this please let me know.
I believe the easiest way to accomplish your goal would be to set up your foreign key with ON DELETE CASCADE. That way, whenever a row in the parent table is deleted, any related rows in the child table will be deleted automatically.
Here is an example of a way to alter a table in order to create a foreign key with ON DELETE CASCADE:
ALTER TABLE child_table
ADD CONSTRAINT fk_name
FOREIGN KEY (child_col1, child_col2, ... child_col_n)
REFERENCES parent_table (parent_col1, parent_col2, ... parent_col_n)
ON DELETE CASCADE;
In your case, the child table would be Buildings and the parent table would be City. It sounds like you would have just city_number for the column. You'll have to fill in the name of your foreign key.
Like Shannon mentioned, you can use ON DELETE CASCADE to delete data from parent and child tables.
Here is a working example:
http://sqlfiddle.com/#!18/f5860/10
Without writing out the code, here's what I would do:
Select all the ids to be deleted for buildings belonging to a city
Delete all the buildings
Delete the city
Put it in a stored procedure
Re-usable, self-contained, and clear.
This is a violation of SRP however, let me know if you care about that and I'll post a SRP based SQL solution.

SQL Server Relation table parent->child and cycle cascade

I have a sql table (let's call it Person) like, for example :
TABLE Person
Id Firstname Lastname
I want to make relations beetwen somme of this person (parent/child relation) so I built another table (let's call it Person_Relation) like that :
TABLE Person_Relation
Id_person_parent Id_person_child
I made a constraint to avoid the case where parent = child (it would be awkward !) and now i try to make foreign key beetwen table Person and table Person_Relation.I am currently able to make one foreign key, but when i try to set the second I get a : may cause cycles or multiple cascade paths error.
Knowing that I would keep the 'Delete cascade' to automatically delete links in Person_Relation table when an entry in Person is deleted, is there any clean solution to do that ?
Thank you in advance.
SQL Server won't let you create multiple cascade paths that could theoretically conflict. For more on that, see this answer.
One way to still achieve your goal is to use a trigger in place of a foreign key with a cascade action.
CREATE TRIGGER dbo.Person_Delete
ON dbo.Person
FOR DELETE
AS
DELETE dbo.Person_Relation
WHERE Id_person_parent IN (SELECT Id FROM deleted)
OR Id_person_child IN (SELECT Id FROM deleted);

multiple cascade paths, on update cascade

I have a problem with sql server, when I want to have 3 table and make relationship between them, and change the "On Update" property to "cascade".
this problem happend when I want to save the diagram:
Introducing FOREIGN KEY constraint 'FK_Company_Slave' on table 'Company' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Could not create constraint. See previous errors.
in this picture, I define my data base, FK and ....
thanks.
First:
A FOREIGN KEY in one table points to a PRIMARY KEY in another table. if you don't want to use PRIMARY KEY on other table in order to foreign key, you must be create unique index on the table.
Second:
you can create after trigger on Master table in order to develop on update cascade manually. In other word your foreign key between Company table and Master table created without on update cascade and then create following trigger on master to update company table after changed row in Master table.
create trigger triggername on dbo.[Master]
After Insert
AS Begin
Update Company
Set MasterKey = I.MasterKey
From Inserted I
Inner join Deleted D on D.Code = I.Code
Where Company.MasterKey = D.MasterKey
End

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

ON UPDATE CASCADE with two columns in a single table in SQL Server [duplicate]

I have a database table called Lesson:
columns: [LessonID, LessonNumber, Description] ...plus some other columns
I have another table called Lesson_ScoreBasedSelection:
columns: [LessonID,NextLessonID_1,NextLessonID_2,NextLessonID_3]
When a lesson is completed, its LessonID is looked up in the Lesson_ScoreBasedSelection table to get the three possible next lessons, each of which are associated with a particular range of scores. If the score was 0-33, the LessonID stored in NextLessonID_1 would be used. If the score was 34-66, the LessonID stored in NextLessonID_2 would be used, and so on.
I want to constrain all the columns in the Lesson_ScoreBasedSelection table with foreign keys referencing the LessonID column in the lesson table, since every value in the Lesson_ScoreBasedSelection table must have an entry in the LessonID column of the Lesson table. I also want cascade updates turned on, so that if a LessonID changes in the Lesson table, all references to it in the Lesson_ScoreBasedSelection table get updated.
This particular cascade update seems like a very straightforward, one-way update, but when I try to apply a foreign key constraint to each field in the Lesson_ScoreBasedSelection table referencing the LessonID field in the Lesson table, I get the error:
Introducing FOREIGN KEY constraint 'c_name' on table 'Lesson_ScoreBasedSelection' may cause cycles or multiple cascade paths.
Can anyone explain why I'm getting this error or how I can achieve the constraints and cascading updating I described?
You can't have more than one cascading RI link to a single table in any given linked table. Microsoft explains this:
You receive this error message because
in SQL Server, a table cannot appear
more than one time in a list of all
the cascading referential actions that
are started by either a DELETE or an
UPDATE statement. For example, the
tree of cascading referential actions
must only have one path to a
particular table on the cascading
referential actions tree.
Given the SQL Server constraint on this, why don't you solve this problem by creating a table with SelectionID (PK), LessonID, Next_LessonID, QualifyingScore as the columns. Use a constraint to ensure LessonID and QualifyingScore are unique.
In the QualifyingScore column, I'd use a tinyint, and make it 0, 1, or 2. That, or you could do a QualifyingMinScore and QualifyingMaxScore column so you could say,
SELECT * FROM NextLesson
WHERE LessonID = #MyLesson
AND QualifyingMinScore <= #MyScore
AND #MyScore <= QualifyingMaxScore
Cheers,
Eric