EF - One to one optional relationship + SQL Server cascade - sql-server

On SQLServer:
Table: FinanceiroLancamento
Id
Name
IdFinanceiroLancamentoCaixa
IdFinanceiroLancamentoBanco
Table: FinanceiroLancamentoCaixa
Id
Money
On EF - Code First for "FinanceiroLancamento":
Property(p => p.Name)
.IsRequired();
HasOptional(p => p.FinanceiroLancamentoCaixa)
.WithMany()
.HasForeignKey(p => p.IdFinanceiroLancamentoCaixa);
On EF - Code First for "FinanceiroLancamentoCaixa":
Property(p => p.Money)
.HasPrecision(15, 2)
.IsRequired();
My SQLServer relationship:
ALTER TABLE FinanceiroLancamento ADD CONSTRAINT [FinanceiroLancamento_003_FKEY] FOREIGN KEY ([IdFinanceiroLancamentoCaixa]) REFERENCES FinanceiroLancamentoCaixa([Id]) ON DELETE CASCADE ON UPDATE CASCADE;
So in the source code I can do:
var money = financeiroLancamento.FinanceiroLancamentoCaixa.Money:
The problem in my relationship is that when I delete "FinanceiroLancamento" it´s not deleting "FinanceiroLancamentoCaixa". But if I delete "FinanceiroLancamentoCaixa" it´s delete "FinanceiroLancamento".
I want the opposite, I would like to delete "FinanceiroLancamento" and it´s delete "FinanceiroLancamentoCaixa". How can I do it?
(I would like to continue with EF navigating from FinanceiroLancamento to FinanceiroLancamentoCaixa)
Thanks.
Best regards,
Wilton Ruffato Wonrath

This is very strangely named. I'm not very fit in EF, but I gather that you want many (or zero or one) FinanceiroLancamentoCaixa records for each FinanceiroLancamento record. The normal way to do this in SQL would have an Id column in both tables plus a "IdFinanceiroLancamento" column in the FinanceiroLancamentoCaixa table.
Then you would define the foreign key as
ALTER TABLE FinanceiroLancamentoCaixa
ADD CONSTRAINT FK_FinanceiroLancamentoCaixa_FinanceiroLancamento
FOREIGN KEY (IdFinanceiroLancamento)
REFERENCES FinanceiroLancamento(Id)
ON DELETE CASCADE
ON UPDATE CASCADE;
Then, when you delete the FinanceiroLancamento record, the cascade deletes also the FinanceiroLancamentoCaixa record(s).

Related

Delete rows from multiple joined tables

I have a problem with removing rows from multiple joined tables in SQL Server.
This is my script:
DELETE d, di, dis
FROM Data d
JOIN DataItem di ON di.DataId = d.DataId
JOIN DataItemSend dis ON dis.DataItemId = di.DataItemId
WHERE d.CardId = 1555
But this syntax is not correct and commas on first line are underlined. How can I solve this problem?
SQL Server does not support deleting from multiple tables at once - unlike MySQL for example.
The way your query is built, however, makes it looks like you could just set up proper foreign keys between the tables, with the on delete cascade option, like so:
alter table DataItem
add constraint fk_DataItem_Data
foreign key (DataId) references Data(DataId)
on delete cascade
;
alter table DataItemSend
add constraint fk_DataItemSend_DataItem
foreign key (DataItemId) references DataItem(DataItemId)
on delete cascade
;
With this set up in place, you can just delete from the top-parent table:
delete from Data where CardId = 1555
... And rest assured that all related records in the children table will be deleted.

Foreign Key with wordpress

I have a table (multisite network) where I use blog_id as one of the columns which is also needed on some of my custom php functions. Until now, I haven't used FK which should be appropriate for my tables.
So, can I FK to wordpress wp_blogs table? if yes, if ever I delete that blog will it also delete the entries on my other tables that references wp_blogs?
CREATE TABLE wp_blogs (blog_id INT NOT NULL...)
FOREIGN KEY (blog_id)
REFERENCES wp_options(blog_id)
ON DELETE CASCADE;
If you created a table like above then every time when blog_id will remove from wp_options then all rows from wp_blogs will remove too.
When you remove rows from wp_blogs then no rows won't remove from wp_options
Read about ON DELETE CASCADE in MySQL documentation.

SQL Server - Cyclic Cascade Path

Lets say I have two tables - User and Post
I introduced a customized Join table Vote to have a many-to-many relationship between User and Post.
The tables have following structure:
User (UseId, Name)
Post (PostId, UserId, Content)
Vote(Id, UserId, PostId, Value)
Notes:
The emphasized columns of each table is a PK.
The UserId in Post is a FK to User table.
The UserId and PostId columns in Vote table are FK to the
respective tables.
Other columns like Value, Content, Name, etc. are varchar.
Considering the above design is appropriate (if not, suggestions are welcomed :) .....
What I want is:
If a row in Post Table is deleted, the related row in Vote should also be deleted.
If a row in User Table is deleted, the related row in Vote should also be deleted.
If a row in User Table is deleted, the related row's UserId column in Post should be set to NULL.
Can I achieve such kind of relationships, without any Cyclic-Redundancy? If yes, How?
UPDATE:
Check out this awesome answer if you too have faced multiple cascade paths:
You are looking for cascading foreign key relationships. For the first two:
alter table vote
add constraint fk_vote_user
foreign key (userid) references user(userid) on delete cascade;
alter table vote
add constraint fk_vote_post
foreign key (postid) references post(postid) on delete cascade;
For the third:
alter table post
add constraint fk_post_user
foreign key (userid) references user(userid) on delete set null;
These are explained in the documentation.
One way is to add isdeleted bit, changed datetime columns to each table and use triggers to update column values on delete. In that case you will keep history of your votes, posts and users.
Or just on delete triggers.
Or to use cascade relationship as Gordon Linoff posted.

How to delete the data in two rows in different table in SQL Server 2012?

How to delete the data in a row in table 1 whose primary key is using as a foreign key in 2nd table.. I am facing the problem here
delete from ASSIGNMENT
where proj_num=18
delete from PROJECT
where proj_num=18
proj_num is the primary key in project and foreign key in assignment.
How to do this task in one delete query ?
You can create/edit the relationship between the two tables in order to set the delete behaviour to ON DELETE CASCADE, then you can just delete the proj_num=18 from the PROJECT table, and it will automatically delete the related records from the ASSIGNMENT table. Hope it works for you.
ALTER TABLE ASSIGNMENT
ADD CONSTRAINT fk_proj
FOREIGN KEY (proj_num)
REFERENCES PROJECT (proj_num)
ON DELETE CASCADE;
Or if you don't have access to the table design you may use this.
DELETE proj
FROM Project AS proj INNER JOIN Assignment AS assn
ON proj.proj_num = asn.proj_num
WHERE proj_num = 18

SQL Server update primary key that's also a foreign key in two tables

I need to update the primary key for a record but it's also the foreign key in two other tables. And I need the updated primary key to be reflected in the child tables as well.
Here is my query and the error:
begin tran
update question set questionparent = 10000, questionid= 10005 where questionid = 11000;
Error 9/4/2009 10:04:49 AM 0:00:00.000 SQL Server Database Error: The UPDATE statement conflicted with the REFERENCE constraint "FK_GoalRequirement_Question". The conflict occurred in database "numgmttest", table "dbo.GoalRequirement", column 'QuestionID'. 14 0
I don't remember how to go about doing this so that's why I'm here. Any help?
Are your relationships using
ON UPDATE CASCADE
If they are then changing the key in the primary table will update the foreign keys.
e.g.
ALTER TABLE Books
ADD CONSTRAINT fk_author
FOREIGN KEY (AuthorID)
REFERENCES Authors (AuthorID) ON UPDATE CASCADE
You may:
disable enforcing FK constraints temporarily (see here or here)
update your PK
update your FKs
enable back enforcing FK constraints
do it all within a transaction and make sure that if transaction fails, you roll it back properly and still enforce the FK constraints back.
But... why do you need to change a PK? I hope this is an action that is executed rarely (legacy data import or something like that).
If you would like to set the Cascade rule graphically then Set Cascade Rule on SQL Management Studio
Open table in design mode
Click Relationship button from top toolbar
Select the required FK relations (one by one)
Right Side - Expand INSERT or UPDATE Specification
Change the UPDATE Rule to - Cascade
Close and Save, Done!
(Tried on SQL 2008)
As I'm not too confident disabling FK constraints, I prefer too :
Duplicate the row with the old PK with one with the new PK
Update the FKs
Delete the row with the old PK
Advantage : No constraint violated during the process.
Go to foreign Key Relations of each child tables and on Insert and Update specification change delete and update rules to cascade.
create a New row with the same data and a different primary key.
update all the children tables.
remove the row that you repeated its data
And its done.

Resources