Welcome to Dream.In.Code
Getting Help is Easy!

Join 117,527 Programmers for FREE! Ask your question and get quick answers from experts. There are 1,989 online right now! We've got more than 500 tutorials and 2,000 snippets. Join and find out why Dream.In.Code is the #1 programming help community on the internet! Registration is fast and FREE... Join Now!



Delete row with Foriegn Key

2 Pages V  1 2 >  
Reply to this topicStart new topic

Delete row with Foriegn Key

rastaman832003
post 17 Jun, 2008 - 11:34 AM
Post #1


D.I.C Head

**
Joined: 29 Feb, 2008
Posts: 58


My Contributions


I am trying to Delete rows from a table that has a foreign key on one of the columns but when i try to execute i get...

Msg 50000, Level 16, State 1, Procedure bat_RethrowError, Line 49
Error: 547, Level: 16, State: 0, Procedure: bat_MoveSheetsToHistory_NonCall, Line: 262, Message: The DELETE statement conflicted with the REFERENCE constraint "FK_Scheduling_SheetStatus_SheetID". The conflict occurred in database "db", table "table.SheetStatus", column 'SheetID'

Here is my Delete statement
CODE

DELETE Scheduling.SheetStatus
    FROM
        Scheduling.SheetStatus AS SSS
        INNER JOIN (
            SELECT *
            FROM @sheetsTable
        ) AS ST ON
            (SSS.SheetID = ST.SheetID)
            AND (SSS.AgentsSignedUp = ST.AgentsSignedUp);
                



any idea what i am doing wrong?

Ok...i think it is actually erroring when i try to delete from the Parent table not from the child table...i do need to delete from both tables.
IE. Delete all from Child table that have the same SheetID as in the parent table, but i was doing this in 2 different delete statements; Parent first and then Child.
is there a way to delete from them both at once?

This post has been edited by rastaman832003: 17 Jun, 2008 - 12:32 PM
User is offlineProfile CardPM

Go to the top of the page


born2c0de
post 17 Jun, 2008 - 12:42 PM
Post #2


printf("I'm a %XR",195936478);

Group Icon
Joined: 26 Nov, 2004
Posts: 3,812



Thanked 27 times

Dream Kudos: 2800

Expert In: 80x86 Assembly, C/C++, VB6, VB.NET, C#, J2SE, Win32 API, Reversing

My Contributions


Set ON DELETE CASCADE for the foreign key.
User is offlineProfile CardPM

Go to the top of the page

rastaman832003
post 17 Jun, 2008 - 01:20 PM
Post #3


D.I.C Head

**
Joined: 29 Feb, 2008
Posts: 58


My Contributions


QUOTE(born2c0de @ 17 Jun, 2008 - 12:42 PM) *

Set ON DELETE CASCADE for the foreign key.

how would i set that in this,When the Primary Key for the table in this Delete is the SkillID, which is the Foreign Key in the table for the Delete statement i posted above?

CODE

DELETE Scheduling.Sheets
    FROM
        Scheduling.Sheets AS SS
        INNER JOIN (
            SELECT *
            FROM @sheetsTable
        ) AS ST ON
            (SS.StartsOn = ST.StartsOn)
            AND (SS.EndsOn = ST.EndsOn)
            AND (SS.Rate = ST.Rate)
            AND (SS.SkillID = ST.SkillID)
            AND (SS.PaySourceID = ST.PaySourceID)
            AND (SS.SheetID = ST.SheetID);


This post has been edited by rastaman832003: 17 Jun, 2008 - 01:23 PM
User is offlineProfile CardPM

Go to the top of the page

rastaman832003
post 18 Jun, 2008 - 12:46 PM
Post #4


D.I.C Head

**
Joined: 29 Feb, 2008
Posts: 58


My Contributions


so any ideas on how i would go about setting up the delete staements to work around that Foriegn Key???
User is offlineProfile CardPM

Go to the top of the page

baavgai
post 19 Jun, 2008 - 05:48 AM
Post #5


Dreaming Coder

Group Icon
Joined: 16 Oct, 2007
Posts: 1,759



Thanked 69 times

Dream Kudos: 400

Expert In: C, C++, Java, C#, ASP.NET, PHP, Perl, Python, Oracle, SQL Server, MySql, HTML, JavaScript, Lua

My Contributions


QUOTE(rastaman832003 @ 17 Jun, 2008 - 02:34 PM) *

i think it is actually erroring when i try to delete from the Parent table not from the child table...i do need to delete from both tables.


Correct! A foreign key says, "there will be no orphans." Meaning the table that has the FK contraint enforces that a parent exists when you add a record. Conversly, when you try to delete a parent that has children, you'll basically get the error you did. You can delete children, the FK constraint doesn't care about that.

What you need to do is find the table that owns the contraint and kill the rows the relate to the parent.

Here's some code that will find all the tables that of FK constraints against your table.
CODE

SELECT FK.TABLE_SCHEMA, FK.TABLE_NAME, FK.CONSTRAINT_NAME, CU.COLUMN_NAME
    FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C
        INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME
        INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME
        INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU ON C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME
    WHERE PK.TABLE_SCHEMA='Scheduling' and PK.TABLE_NAME = 'SheetStatus'
    order by FK.TABLE_SCHEMA, FK.TABLE_NAME, FK.CONSTRAINT_NAME, CU.COLUMN_NAME, CU.ORDINAL_POSITION


I'm going to assume that one of the kids was "table.SheetStatus", given your error. ( Bad name, that, but it's what we have to work with. ) Before we kill the parents, we kill the kids.

CODE

DELETE table.SheetStatus
    FROM table.SheetStatus a
    INNER JOIN @sheetsTable b
        ON a.SheetID = b.SheetID


Then the parents:
CODE

DELETE Scheduling.SheetStatus
    FROM table.SheetStatus a
    INNER JOIN @sheetsTable b
        ON a.SheetID = b.SheetID


You have to adjust based on column names, of course.

Hope this helps.
User is online!Profile CardPM

Go to the top of the page

rastaman832003
post 19 Jun, 2008 - 07:10 AM
Post #6


D.I.C Head

**
Joined: 29 Feb, 2008
Posts: 58


My Contributions


Right now i have the delete for the Parent first, So if i delete the info from the Child table first then i shouldnt run into the foriegn key issue at all?
User is offlineProfile CardPM

Go to the top of the page

baavgai
post 19 Jun, 2008 - 08:08 AM
Post #7


Dreaming Coder

Group Icon
Joined: 16 Oct, 2007
Posts: 1,759



Thanked 69 times

Dream Kudos: 400

Expert In: C, C++, Java, C#, ASP.NET, PHP, Perl, Python, Oracle, SQL Server, MySql, HTML, JavaScript, Lua

My Contributions


Yep, no children, no constraint.

As noted previously, you can define a foreign key to automatically drop the child tables. I often prefer to do it manually, having the logic in procedures and yelling at those who might delete something by mistake.

This post has been edited by baavgai: 19 Jun, 2008 - 08:08 AM
User is online!Profile CardPM

Go to the top of the page

rastaman832003
post 19 Jun, 2008 - 08:22 AM
Post #8


D.I.C Head

**
Joined: 29 Feb, 2008
Posts: 58


My Contributions


QUOTE(baavgai @ 19 Jun, 2008 - 08:08 AM) *

Yep, no children, no constraint.

As noted previously, you can define a foreign key to automatically drop the child tables. I often prefer to do it manually, having the logic in procedures and yelling at those who might delete something by mistake.


Yea...i think in my case its best to have the Delete logic for both instead of having the Delete from Parent cascade down to the child. Thanks, you tha man Baavgai!
User is offlineProfile CardPM

Go to the top of the page

rastaman832003
post 19 Jun, 2008 - 11:31 AM
Post #9


D.I.C Head

**
Joined: 29 Feb, 2008
Posts: 58


My Contributions


ok...after changing the order of the select staement i have no more issue with the foriegn key...but i have a new issue...
I have 2 variable, one is a smallint that represents the number of days before something should be moved to a new table, the second is a datetime value that represents the cut off date for something to be deleted(based on the date run)....so i am getting a arithmetic overflow error when using this code...
CODE

@archiveDays smallint = 8,
@deleteCutOffDate datetime = NULL OUTPUT,
    
/*
     * If @archiveDays is zero, then the cut-off date is now, otherwise Set the cutoff date to
     * {@archiveDays} prior to today and the cutoff time to the end of that day.
     */
    IF (@archiveDays = 0) BEGIN
        SET @deleteCutOffDate = GetDate();
    END ELSE BEGIN
        SET @deleteCutOffDate = DateAdd(day, -archiveDays, GetDate());
        SET @deleteCutOffDate = Cast((Convert(varchar, @deleteCutOffDate , 101) + ' 23:59:59') AS datetime);
    END;


any idea of another way i could convert these so as not to get the error?
User is offlineProfile CardPM

Go to the top of the page

baavgai
post 19 Jun, 2008 - 12:12 PM
Post #10


Dreaming Coder

Group Icon
Joined: 16 Oct, 2007
Posts: 1,759



Thanked 69 times

Dream Kudos: 400

Expert In: C, C++, Java, C#, ASP.NET, PHP, Perl, Python, Oracle, SQL Server, MySql, HTML, JavaScript, Lua

My Contributions


Looks like a typo. Overflow seems a little drastic, I expect it would have just warned you. tongue.gif

Anyway, make this -archiveDays this -@archiveDays.
User is online!Profile CardPM

Go to the top of the page

rastaman832003
post 19 Jun, 2008 - 12:31 PM
Post #11


D.I.C Head

**
Joined: 29 Feb, 2008
Posts: 58


My Contributions


QUOTE(baavgai @ 19 Jun, 2008 - 12:12 PM) *

Looks like a typo. Overflow seems a little drastic, I expect it would have just warned you. tongue.gif

Anyway, make this -archiveDays this -@archiveDays.

that was actually a typo just in here...in the actual code i did have the @...
and this is the error i get...

Arithmetic overflow error converting expression to data type datetime.
User is offlineProfile CardPM

Go to the top of the page

baavgai
post 19 Jun, 2008 - 02:47 PM
Post #12


Dreaming Coder

Group Icon
Joined: 16 Oct, 2007
Posts: 1,759



Thanked 69 times

Dream Kudos: 400

Expert In: C, C++, Java, C#, ASP.NET, PHP, Perl, Python, Oracle, SQL Server, MySql, HTML, JavaScript, Lua

My Contributions


Try making @archiveDays an int, just to be on the safe side. However, I ran this at work without issue, so I'm not sure where you're getting hit.

Here's my test code:

CODE

declare @archiveDays int
declare @deleteCutOffDate datetime
    
set @archiveDays=8
IF (@archiveDays = 0) BEGIN
    SET @deleteCutOffDate = GetDate();
END ELSE BEGIN
    SET @deleteCutOffDate = DateAdd(day, -@archiveDays, GetDate());
    SET @deleteCutOffDate = Cast((Convert(varchar, @deleteCutOffDate , 101) + ' 23:59:59') AS datetime);
END;

print @deleteCutOffDate
go

User is online!Profile CardPM

Go to the top of the page

2 Pages V  1 2 >
Fast ReplyReply to this topicStart new topic
Time is now: 10/7/08 03:43PM

Live Help!

Tutorials

Programming

Web Development

Reference Sheets

Code Snippets

Bye Bye Ads

Free DIC T-Shirt

T-Shirt Example

Related Sites

Monthly Drawing

Thumb Drive

Partners

Top Contributors

Top 10 Kudos This Month