Home All Groups Group Topic Archive Search About

Script to delete records from a table older than N number of days.



Author
3 Dec 2008 4:51 AM
Fuel451
I have a table within a SQL 2005 database that fills up after about three
months and I'd like to schedule a daily job to delete rows or records older
than 60 or 90 days.

Could someone provide the syntax for a DELETE script?

Thanks in advance.

Author
3 Dec 2008 4:56 AM
Jonathan Kehayias
The following is one way to do it while minimizing the transaction length
and impact of locking on the table:

DECLARE @BatchSize INT,
        @Criteria DATETIME,
        @RowCount INT
SET @BatchSize = 1000
SET @Criteria = getdate()-60
SET @RowCount = 1000
SET ROWCOUNT @BatchSize
WHILE @RowCount > 0
BEGIN
    DELETE
    FROM MYTABLE
    WHERE MYCOL < @Criteria
    SELECT @RowCount = @@rowcount
END
SET ROWCOUNT 0


--
Jonathan Kehayias
SQL Server MVP
http://jmkehayias.blogspot.com
http://www.sqlclr.net


Show quoteHide quote
"Fuel451" <Fuel***@discussions.microsoft.com> wrote in message
news:71C408F1-EB4A-45B6-A054-899D24602A03@microsoft.com...
>I have a table within a SQL 2005 database that fills up after about three
> months and I'd like to schedule a daily job to delete rows or records
> older
> than 60 or 90 days.
>
> Could someone provide the syntax for a DELETE script?
>
> Thanks in advance.
Are all your drivers up to date? click for free checkup

Author
3 Dec 2008 5:15 AM
Plamen Ratchev
In the next release of SQL Server (after SQL Server 2008) SET ROWCOUNT
will not affect DELETE, INSERT, and UPDATE statements. It is better to
use TOP to limit the number of rows deleted.

DELETE TOP (@BatchSize) FROM...

--
Plamen Ratchev
http://www.SQLStudio.com
Author
3 Dec 2008 5:42 AM
Jonathan Kehayias
Thanks for point that out.  It is documented as such in the 2008 BOL.
However, you should still use TOP to limit the number of affected rows at a
time as follows to minimize impact and duration of the process:

DECLARE @Criteria DATETIME,
        @RowCount INT
SET @Criteria = getdate()-60
WHILE @RowCount = 1000
BEGIN
    DELETE TOP(1000)
    FROM MYTABLE
    WHERE MYCOL < @Criteria

    SELECT @RowCount = @@rowcount
END

Doing a single delete as in your other post is generally less efficient and
takes more time than batching it in smaller groups.  In SIMPLE recovery, it
also causes the transaction log to grow needlessly since it can't truncate
on checkpoint until the entire delete is completed and commited.

--
Jonathan Kehayias
SQL Server MVP
http://jmkehayias.blogspot.com
http://www.sqlclr.net


Show quoteHide quote
"Plamen Ratchev" <Pla***@SQLStudio.com> wrote in message
news:8ZOdnYbnfO2ci6vUnZ2dnUVZ_qfinZ2d@speakeasy.net...
> In the next release of SQL Server (after SQL Server 2008) SET ROWCOUNT
> will not affect DELETE, INSERT, and UPDATE statements. It is better to use
> TOP to limit the number of rows deleted.
>
> DELETE TOP (@BatchSize) FROM...
>
> --
> Plamen Ratchev
> http://www.SQLStudio.com
Author
3 Dec 2008 5:53 AM
Plamen Ratchev
I agree on the batch delete comments. But if you will be running this
process daily as indicated, I doubt there will be a million or more rows
  to delete every day.

--
Plamen Ratchev
http://www.SQLStudio.com
Author
3 Dec 2008 5:10 AM
Plamen Ratchev
If you will be deleting daily those rows, then probably a simple delete
statement like this will do:

DELETE FROM Foo
WHERE foo_date <= DATEADD(DAY,
                           DATEDIFF(DAY,
                                    '20010101',
                                    CURRENT_TIMESTAMP) - 60,
                           '20010101');

The DATEDIFF function is used to trim the time portion of the current
date so you do not get partial day removed. Also, you can set 60 as
parameter.

--
Plamen Ratchev
http://www.SQLStudio.com
Author
3 Dec 2008 5:56 AM
Jonathan Kehayias
This can easily be a long running transaction that causes excessive log
growth and blocking in the database while it runs needlessly depending on
the number of rows being deleted each time it runs.  A batched delete using
SET ROWCOUNT in older versions of SQL Server or TOP(N) moving forward
overcomes both of these problems by minimizing the duration of each actual
delete statement.

--
Jonathan Kehayias
SQL Server MVP
http://jmkehayias.blogspot.com
http://www.sqlclr.net


Show quoteHide quote
"Plamen Ratchev" <Pla***@SQLStudio.com> wrote in message
news:8ZOdnYfnfO17iavUnZ2dnUVZ_qfinZ2d@speakeasy.net...
> If you will be deleting daily those rows, then probably a simple delete
> statement like this will do:
>
> DELETE FROM Foo
> WHERE foo_date <= DATEADD(DAY,
>                           DATEDIFF(DAY,
>                                    '20010101',
>                                    CURRENT_TIMESTAMP) - 60,
>                           '20010101');
>
> The DATEDIFF function is used to trim the time portion of the current date
> so you do not get partial day removed. Also, you can set 60 as parameter.
>
> --
> Plamen Ratchev
> http://www.SQLStudio.com
Author
3 Dec 2008 1:52 PM
Paul Cahill
SET ROWCOUNT will be in effect for any triggers. This could give rise to
orphan rows.
Author
4 Dec 2008 1:30 AM
Jonathan Kehayias
Cascading constraints should enforce that kind of logic, not triggers.  If
your constraints are enabled with check, the transaction should halt and
rollback to prevent the constraint violation.

--
Jonathan Kehayias
SQL Server MVP
http://jmkehayias.blogspot.com
http://www.sqlclr.net


Show quoteHide quote
"Paul Cahill" <a***@anon.com> wrote in message
news:0D383B55-5C2D-47A6-9DFB-C3232F56550C@microsoft.com...
> SET ROWCOUNT will be in effect for any triggers. This could give rise to
> orphan rows.
>
>
>
>
>

Bookmark and Share