Showing posts with label certain. Show all posts
Showing posts with label certain. Show all posts

Thursday, March 29, 2012

Deleting records from multiple tables in SQL server

I'm new to relational database concepts and designs, but what i've learned so far has been helpful. I now know how to select certain records from multiple tables using joins, etc. Now I need info on how to do complete deletes. I've tried reading articles on cascading deletes, but the people writing them are so verbose that they are confusing to understand for a beginner. I hope someone could help me with this problem.

I have sql server 2005. I use visual studio 2005. In the database I've created the following tables(with their column names):

Table 1: Classes --Columns: ClassID, ClassName

Table 2: Roster--Columns: ClassID, StudentID, Student Name

Table 3: Assignments--Columns: ClassID, AssignmentID, AssignmentName

Table 4: Scores--StudentID, AssignmentID, Score

What I can't seem to figure out is how can I delete a class (ClassID) from Classes and as a result of this one deletion, delete all students in the Roster table associated with that class, delete all assignments associated with that class, delete all scores associated with all assignments associated with that class in one DELETE sql statement.

What I tried to do in sql server management studio is set the ClassID in Classes as a primary key, then set foreign keys to the other three tables. However, also set AssignmentID in Table 4 as a foreign key to Table 3.

The stored procedure I created was

DELETE FROM Classes WHERE ClassID=@.classid

I thought, since I established ClassID as a primary key in Classes, that by deleting it, it would also delete all other rows in the foreign tables that have the same value in their ClassID columns. But I get errors when I run the query. The error said:

The DELETE statement conflicted with the REFERENCE constraint "FK_Roster_Classes1". The conflict occurred in database "database", table "dbo.Roster", column 'ClassID'.
The statement has been terminated.

What are reference constraints? What are they talking about? Plus is the query correct? If not, how would I go about solving my problem. Would I have to do joins while deleting?

I thought I was doing a cascade delete. The articles I read kept insisting that cascade deletes are deletes where if you delete a record from a parent table, then the rows in the child table will also be deleted, but I get the error.

Did I approach this right? If not, please show me how, and please, please explain it like I'm a four year old.

Further, is there something else I need to do besides assigning primary keys and foreign keys?

WHen you create a foreign key, there are some additional options you have to set to tell it to do the cascade delete.

If you are creating the foreign key through T-SQL you must append the ON DELETE CASCADE option to the foreign key:

Code Snippet

ALTER TABLE <tablename>
ADD CONSTRAINT <constraintname> FOREIGN KEY (<columnname(s)>)
REFERENCES <referencedtablename> (<columnname(s)>)

ON DELETE CASCADE;

If using SSMS, modify the table and go to where you created the relationship. If you look around in there you should see an option to set the "Delete Rule" Set that to CASCADE.


|||

OK, the concept of deleting rows from multiple tables in a single delete statement cannot be done in just that statement. There is the concept of triggers on the tables that do deletes in a cascading style, but I would not recommend you do it that way for sake of control of the actions of the data.

But I udnerstand what you want to do, and the best way to explain it is this:

Say you have these tables and each one has a relationship up the chain. If you have Classes, and they are on Rosters, and Assignments are given to Classes and Scores have Students and Assignments you have to see which is the last one in the chain.

So in your case you have Classes that is the base and then you have Classes in Rosters (this is the next level) and you have Classes in Assignments (same level as Rosters).

So you have a relationship like

Classes - ClassID

|__Roster - ClassId

|__Assignments - ClassId

|Scores - AssignmentId

So say you no longer had ClassId 3 and you wanted to just get rid of all the records that are associated with ClassId 3. Here are the steps that you would need to take. You would delete in the reverse order than you inserted.

So in this case, you would want to use the ClassId = 3 to get all the assignments that have that ClassId and delete the Scores that have the AssignmentId and then delete the Assignments with the ClassId = 3

Then you would delete the Rosters with the ClassId = 3 and then finally delete the Classes with ClassId = 3

SQL:

DELETE Scores

FROM Assignments A

INNER JOIN Scores S ON A.AssignmentId = S.AssignmentId

WHERE A.ClassId = 3

DELETE Assignments

WHERE ClassId = 3

DELETE Roster

WHERE ClassId = 3

DELETE Classes

WHERE ClassId = 3

So you really just need to delete the Foreign Key tables records with the Primary Key record in it first and then delete the Primary Key records in the Primary table or Base table last.

HTH.

Ben Miller

|||I disagree with you an the answer that this cannot be done within one statement as the suggestions from Andrew about Cascading deletes should solve the problem, if the architecture is appropiate for the original poster.

Jens K. Suessmeyer.

http://www.sqlserver2005.de
|||

Ben

I also disagree with your presentation. With a properly established set of relationships, CASCADE DELETE works wonderfully. The PK-FK relationships must be properly set-up, and there cannot be any circular relationships.

So you have a relationship like

Classes - ClassID

|__Roster - ClassId

|__Assignments - ClassId

|Scores - AssignmentId

In this situation, a deletion on [Classes] will remove related data from all lower tables. Deleting [Assignments] will also delete related data from [Scores]. A deletion on [Roster] or [Scores] will only affect those tables.

Wednesday, March 21, 2012

Deleting data from a column

What is the command to delete data from certain named colums but
otherwise leave the column intact and also leave the rows and unnamed
columns intact?The following syntax will replace the existing data in the specified columns
with NULL. Without a WHERE clause it will update every row in the table.
If you only want to modify some subset of rows, you'll need to specify the
appropriate WHERE clause.
UPDATE table
SET column_name1 = NULL, column_name2 = NULL, etc.
--
Gail Erickson [MS]
SQL Server Documentation Team
This posting is provided "AS IS" with no warranties, and confers no rights
Download the latest version of Books Online from
http://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books.mspx
"RocketMan" <ImaChessNut@.gmail.com> wrote in message
news:1181246690.348694.107840@.i38g2000prf.googlegroups.com...
> What is the command to delete data from certain named colums but
> otherwise leave the column intact and also leave the rows and unnamed
> columns intact?
>|||Hi
Its the UPDATE command
e.g
update table set column=null where x=1
see BOL for more info
Regards
VT
Knowledge is power, share it...
http://oneplace4sql.blogspot.com/
"RocketMan" <ImaChessNut@.gmail.com> wrote in message
news:1181246690.348694.107840@.i38g2000prf.googlegroups.com...
> What is the command to delete data from certain named colums but
> otherwise leave the column intact and also leave the rows and unnamed
> columns intact?
>

Deleting data from a column

What is the command to delete data from certain named colums but
otherwise leave the column intact and also leave the rows and unnamed
columns intact?
The following syntax will replace the existing data in the specified columns
with NULL. Without a WHERE clause it will update every row in the table.
If you only want to modify some subset of rows, you'll need to specify the
appropriate WHERE clause.
UPDATE table
SET column_name1 = NULL, column_name2 = NULL, etc.
Gail Erickson [MS]
SQL Server Documentation Team
This posting is provided "AS IS" with no warranties, and confers no rights
Download the latest version of Books Online from
http://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books.mspx
"RocketMan" <ImaChessNut@.gmail.com> wrote in message
news:1181246690.348694.107840@.i38g2000prf.googlegr oups.com...
> What is the command to delete data from certain named colums but
> otherwise leave the column intact and also leave the rows and unnamed
> columns intact?
>

Deleting data from a column

What is the command to delete data from certain named colums but
otherwise leave the column intact and also leave the rows and unnamed
columns intact?The following syntax will replace the existing data in the specified columns
with NULL. Without a WHERE clause it will update every row in the table.
If you only want to modify some subset of rows, you'll need to specify the
appropriate WHERE clause.
UPDATE table
SET column_name1 = NULL, column_name2 = NULL, etc.
Gail Erickson [MS]
SQL Server Documentation Team
This posting is provided "AS IS" with no warranties, and confers no rights
Download the latest version of Books Online from
http://www.microsoft.com/technet/pr...oads/books.mspx
"RocketMan" <ImaChessNut@.gmail.com> wrote in message
news:1181246690.348694.107840@.i38g2000prf.googlegroups.com...
> What is the command to delete data from certain named colums but
> otherwise leave the column intact and also leave the rows and unnamed
> columns intact?
>|||Hi
Its the UPDATE command
e.g
update table set column=null where x=1
see BOL for more info
Regards
VT
Knowledge is power, share it...
http://oneplace4sql.blogspot.com/
"RocketMan" <ImaChessNut@.gmail.com> wrote in message
news:1181246690.348694.107840@.i38g2000prf.googlegroups.com...
> What is the command to delete data from certain named colums but
> otherwise leave the column intact and also leave the rows and unnamed
> columns intact?
>

Deleting certain text patterns from a column

Hi,
I have a column in SQL DB and the column contains the information like:
<ProductDescription>This TV is good. </ProductDescription> This TV is sold
out.
<ProductDescription>This TV is bad. </ProductDescription> This TV is not
selling well.
(By the way, I am NOT talking about the XML-formatted SQL DB, which was
introduced in SQL 2000. The tag is just text mainly used for human
consumption.)
I want to delete all the text between <ProductDescription> and
</ProductDescription>, including the tags from the column. Is it possible?
It looks like the Replace function cannot take wildcard character and I am
thinking doing it programmatically, like with C#, is the only way. I
appreciate your help!Try something like this:
declare @.tag varchar(30)
declare @.test varchar(8000)
set @.test = 'Don''t get <tag> get rid of this </tag>rid of outside stuff'
set @.tag = 'tag'
select
stuff(@.test,charindex('<'+@.tag+'>',@.test),charindex('</'+@.tag+'>',@.test) +
len(@.tag) + 2,'')
----
Louis Davidson - http://spaces.msn.com/members/drsql/
SQL Server MVP
"Kevin" <no_spam@.nospamfordiscussion.com> wrote in message
news:OfqSCkMYFHA.1736@.tk2msftngp13.phx.gbl...
> Hi,
> I have a column in SQL DB and the column contains the information like:
> <ProductDescription>This TV is good. </ProductDescription> This TV is sold
> out.
> <ProductDescription>This TV is bad. </ProductDescription> This TV is not
> selling well.
> (By the way, I am NOT talking about the XML-formatted SQL DB, which was
> introduced in SQL 2000. The tag is just text mainly used for human
> consumption.)
> I want to delete all the text between <ProductDescription> and
> </ProductDescription>, including the tags from the column. Is it possible?
> It looks like the Replace function cannot take wildcard character and I am
> thinking doing it programmatically, like with C#, is the only way. I
> appreciate your help!
>
>|||Thanks! Didn't think of using that function.
"Louis Davidson" <dr_dontspamme_sql@.hotmail.com> wrote in message
news:%23o1nh9MYFHA.2588@.TK2MSFTNGP14.phx.gbl...
> Try something like this:
> declare @.tag varchar(30)
> declare @.test varchar(8000)
> set @.test = 'Don''t get <tag> get rid of this </tag>rid of outside stuff'
> set @.tag = 'tag'
> select
> stuff(@.test,charindex('<'+@.tag+'>',@.test),charindex('</'+@.tag+'>',@.test) +
> len(@.tag) + 2,'')
> --
> ----
--
> Louis Davidson - http://spaces.msn.com/members/drsql/
> SQL Server MVP
>
> "Kevin" <no_spam@.nospamfordiscussion.com> wrote in message
> news:OfqSCkMYFHA.1736@.tk2msftngp13.phx.gbl...
>

Sunday, March 11, 2012

DeletedFlag field and unique keys

I was thinking of using a deleted flag rather then deleting a record so that history (auditing, etc.) could be maintained. In certain tables I would like to preserve a unique key on a field (say name or code) of all non-deleted records. Is there any way to do this. I cannot have a Code + DeletedFlag field because there may be multiple records that have been deleted with the same code. I also don't want to include the deleted "codes" in the unique key because I want the user to be able to see the codes they can't use without viewing the deleted records.May be Code+DeletedFlag+DeletedDateTime could be good idea|||That means there could be duplicate codes for active entries which is what I am trying to avoid.|||You could always keep a separate table for the deleted items (with _deleted at the end of the name, or a similar convention). I do this now and then. The deleted items table wouldn't have the uniqueness constraints on it, and you could still use a view to look at the combined tables. Then slap an AFTER DELETE trigger on the original table to automatically move rows into the deleted items table.
|||

A 'better' way to handle archiving is to have separate archiving tables. Same schema, no IDENTITY fields, no constraints, index only on PK, a couple of additional columns:

ChangeBy varchar(50)DEFAULT system_user ChangeDate datetime DEFAULT getdate()|||I have thought about another table (deleted or archived) for records and that probably is the most sensible way to deal with this issue. Ideally I wanted to create an audit table and for any table I wanted to audit I would have a join table (transaction_audit for example). The audit record would hold time, user, action (cud), ip, etc. This way when looking at any record from an audited table you could see a list of actions that were performed on it. Maybe not the complete history (every changed value) which might be overkill but who did what (in general) to it when and from where. Deleted records would be kept in the database in their last state so that activity would be shown as activity and not masked.|||I agree with Arnie.

I do this all the time. Create a table exactly like the original with no identity or constraints with a few extra fields on the end, like ChangeType, UserID, ChangeDateTime, called tablename_audit. Then setup a trigger to "insert into table_audit select *, "D", @.userid, getdate() from deleted" the audit table.

The only thing you need to remember with this is, when you change the original, you MUST also change the fields in the audit log to match. This can take some time, if you have many audit records.

DeletedFlag field and unique keys

I was thinking of using a deleted flag rather then deleting a record so that history (auditing, etc.) could be maintained. In certain tables I would like to preserve a unique key on a field (say name or code) of all non-deleted records. Is there any way to do this. I cannot have a Code + DeletedFlag field because there may be multiple records that have been deleted with the same code. I also don't want to include the deleted "codes" in the unique key because I want the user to be able to see the codes they can't use without viewing the deleted records.May be Code+DeletedFlag+DeletedDateTime could be good idea|||That means there could be duplicate codes for active entries which is what I am trying to avoid.|||You could always keep a separate table for the deleted items (with _deleted at the end of the name, or a similar convention). I do this now and then. The deleted items table wouldn't have the uniqueness constraints on it, and you could still use a view to look at the combined tables. Then slap an AFTER DELETE trigger on the original table to automatically move rows into the deleted items table.
|||

A 'better' way to handle archiving is to have separate archiving tables. Same schema, no IDENTITY fields, no constraints, index only on PK, a couple of additional columns:

ChangeBy varchar(50)DEFAULT system_user ChangeDate datetime DEFAULT getdate()|||I have thought about another table (deleted or archived) for records and that probably is the most sensible way to deal with this issue. Ideally I wanted to create an audit table and for any table I wanted to audit I would have a join table (transaction_audit for example). The audit record would hold time, user, action (cud), ip, etc. This way when looking at any record from an audited table you could see a list of actions that were performed on it. Maybe not the complete history (every changed value) which might be overkill but who did what (in general) to it when and from where. Deleted records would be kept in the database in their last state so that activity would be shown as activity and not masked.|||I agree with Arnie.

I do this all the time. Create a table exactly like the original with no identity or constraints with a few extra fields on the end, like ChangeType, UserID, ChangeDateTime, called tablename_audit. Then setup a trigger to "insert into table_audit select *, "D", @.userid, getdate() from deleted" the audit table.

The only thing you need to remember with this is, when you change the original, you MUST also change the fields in the audit log to match. This can take some time, if you have many audit records.

Friday, March 9, 2012

Deleted Revords

Hi All,
Is there any way I can find out who deleted certain records from the
database in last month or so. Someone deleted few records from one of the sq
l
server 2000 db with sp3 on it. Is there a easy way to find this?
Thanks
AndyIf you have the log backups from then you might be able to use one of the
3rd party log viewer tools. I know the one from lumigent looks at log
backups but not sure about the others.
www.lumigent.com
Andrew J. Kelly SQL MVP
"Andy" <Andy@.discussions.microsoft.com> wrote in message
news:BB4944F7-B4B9-49A5-91CA-242693A2B5B5@.microsoft.com...
> Hi All,
> Is there any way I can find out who deleted certain records from the
> database in last month or so. Someone deleted few records from one of the
> sql
> server 2000 db with sp3 on it. Is there a easy way to find this?
> Thanks
> Andy

Sunday, February 19, 2012

Delete records older than a certain period from the subscriber

Hi,
I am struggling with this for some time now:
I want all records older than a certain period (eg. one month) to be
deleted from the subscriber's database.
I have created sample database with only one table and one datetime
column, just for testing this. The table is filtered:
SELECT <published_columns> FROM [dbo].[table] WHERE DateField >=
DateAdd(month,-1,GetDate()) - so subscriber should only have records
entered last month.
So, if subscriber enters one record in the subscription db with
today's date and synchronizes immediatelly, record will remain in the
subscriber's database which is OK, but I want this record to be
removed from the subscriber's database when user will synchronize
someday in the future and this record will be older than a month.
However, this does not happen. I know that record won't be sent to the
publisher as a part of merge replication, if it was not changed
between synchronizations. For that reason, an update to the same value
is always performed on the subscriber's table before the
synchronization, eg. update table set datefield = datefield.
I can see in the merge agent history that this update is sent to the
publisher, but record still remains in the subscriber's db. It seems
to me that filter is not evaluated correctly or not evaluated at all.
If I specify reinitialization on the subscription, the record is
removed from the subscribers database, but I do not want to
reinitialize at each sync.
I have read numerous posts and noticed that this scenario should
work?!
Any idea what might be wrong?
I am using SQL 2000 with SP3.
Janez
I think you will have to run a job on the subscriber which will delete rows
which are older than a month.
The merge filter only filters modified/deleted/inserted rows. Not rows which
are not touched.
Hilary Cotter
Looking for a SQL Server replication book?
Now available for purchase at:
http://www.nwsu.com/0974973602.html
"Janez" <janezcas@.yahoo.com> wrote in message
news:c697ea9c.0412080703.1135f892@.posting.google.c om...
> Hi,
> I am struggling with this for some time now:
> I want all records older than a certain period (eg. one month) to be
> deleted from the subscriber's database.
> I have created sample database with only one table and one datetime
> column, just for testing this. The table is filtered:
> SELECT <published_columns> FROM [dbo].[table] WHERE DateField >=
> DateAdd(month,-1,GetDate()) - so subscriber should only have records
> entered last month.
> So, if subscriber enters one record in the subscription db with
> today's date and synchronizes immediatelly, record will remain in the
> subscriber's database which is OK, but I want this record to be
> removed from the subscriber's database when user will synchronize
> someday in the future and this record will be older than a month.
> However, this does not happen. I know that record won't be sent to the
> publisher as a part of merge replication, if it was not changed
> between synchronizations. For that reason, an update to the same value
> is always performed on the subscriber's table before the
> synchronization, eg. update table set datefield = datefield.
> I can see in the merge agent history that this update is sent to the
> publisher, but record still remains in the subscriber's db. It seems
> to me that filter is not evaluated correctly or not evaluated at all.
> If I specify reinitialization on the subscription, the record is
> removed from the subscribers database, but I do not want to
> reinitialize at each sync.
> I have read numerous posts and noticed that this scenario should
> work?!
> Any idea what might be wrong?
> I am using SQL 2000 with SP3.
> Janez
|||Hi Hilary,
thanks for your response.
About your suggestion: I have thought about this too, but I believe that
this would delete the records also from the publisher at next sync which
is not what I want. I want only one month old records in the
subscriber's database, but publisher should have all records not just
one month old.
Another thing:
What do you mean by 'not touched'?
I always update records at the subscriber before each sync with the
dummy update of the date field to the same value, but the filter is not
evaluated.
Should this dummy update be enough to trigger filter evaluation?!
Regards
Janez
*** Sent via Developersdex http://www.codecomments.com ***
Don't just participate in USENET...get rewarded for it!
|||For that form of logic I normally use bi-directional transactional
replication.
Hilary Cotter
Looking for a SQL Server replication book?
Now available for purchase at:
http://www.nwsu.com/0974973602.html
"Janez Cas" <janezcas@.yahoo.com> wrote in message
news:eUUJG8U3EHA.1264@.TK2MSFTNGP12.phx.gbl...
> Hi Hilary,
> thanks for your response.
> About your suggestion: I have thought about this too, but I believe that
> this would delete the records also from the publisher at next sync which
> is not what I want. I want only one month old records in the
> subscriber's database, but publisher should have all records not just
> one month old.
> Another thing:
> What do you mean by 'not touched'?
> I always update records at the subscriber before each sync with the
> dummy update of the date field to the same value, but the filter is not
> evaluated.
> Should this dummy update be enough to trigger filter evaluation?!
> Regards
> Janez
>
> *** Sent via Developersdex http://www.codecomments.com ***
> Don't just participate in USENET...get rewarded for it!