Created
July 15, 2025 10:20
-
-
Save farseenmanekhan1232/8ba31bec347363308dd991dc3b4bad8f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
================================================================================================ | |
SCRIPT TO DELETE ALL BUT THE TOP 5000 ROWS FROM EACH TABLE IN A DATABASE (REVISED) | |
================================================================================================ | |
-- | |
-- HOW TO USE: | |
-- 1. Make a file copy of your .mdf and .ldf files. | |
-- 2. Attach the copied files as a NEW database in SSMS (e.g., 'Gas5000'). | |
-- 3. CHANGE the database name in the 'USE' statement below to your new database. | |
-- 4. Execute this script. | |
-- | |
-- WHAT IT DOES: | |
-- This script iterates through every user table in the specified database. For each table, | |
-- it identifies which rows to KEEP based on an ordering principle and deletes all others. | |
-- | |
-- !! IMPORTANT NOTE ON "TOP 5000 ROWS" !! | |
-- SQL tables are inherently unordered. To determine the "top" rows, we must ORDER BY a | |
-- column. This script automatically tries to use the table's primary key. If no primary | |
-- key is found, it uses the first column of the table as a fallback. | |
-- | |
================================================================================================ | |
*/ | |
-- <<-- 1. SET THE NAME OF YOUR COPIED DATABASE HERE | |
USE [Gas5000]; | |
GO | |
SET NOCOUNT ON; | |
DECLARE @schemaName NVARCHAR(128); | |
DECLARE @tableName NVARCHAR(128); | |
DECLARE @orderByColumn NVARCHAR(128); | |
DECLARE @sql NVARCHAR(MAX); | |
DECLARE @fullTableName NVARCHAR(257); -- schema.table | |
PRINT 'Starting data trim process for database: ' + QUOTENAME(DB_NAME()); | |
PRINT '================================================================'; | |
-- Declare a cursor to loop through all user tables in the current database. | |
DECLARE table_cursor CURSOR FOR | |
SELECT s.name, t.name | |
FROM sys.tables AS t | |
INNER JOIN sys.schemas AS s ON t.schema_id = s.schema_id | |
WHERE t.type = 'U' -- User Table | |
AND t.is_ms_shipped = 0 | |
ORDER BY s.name, t.name; | |
OPEN table_cursor; | |
FETCH NEXT FROM table_cursor INTO @schemaName, @tableName; | |
WHILE @@FETCH_STATUS = 0 | |
BEGIN | |
SET @fullTableName = QUOTENAME(@schemaName) + '.' + QUOTENAME(@tableName); | |
PRINT 'Processing table: ' + @fullTableName; | |
-- Reset the ordering column for each table | |
SET @orderByColumn = NULL; | |
-- Try to find the primary key column to use for ordering. | |
SELECT TOP 1 @orderByColumn = c.name | |
FROM sys.indexes AS i | |
INNER JOIN sys.index_columns AS ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id | |
INNER JOIN sys.columns AS c ON ic.object_id = c.object_id AND c.column_id = ic.column_id | |
WHERE i.is_primary_key = 1 AND i.object_id = OBJECT_ID(@fullTableName); | |
-- If no primary key, find the first column of the table as a fallback. | |
IF @orderByColumn IS NULL | |
BEGIN | |
SELECT TOP 1 @orderByColumn = name | |
FROM sys.columns | |
WHERE object_id = OBJECT_ID(@fullTableName) | |
ORDER BY column_id; | |
PRINT ' -> No primary key found. Using first column for ordering: ' + QUOTENAME(@orderByColumn); | |
END | |
ELSE | |
BEGIN | |
PRINT ' -> Using primary key for ordering: ' + QUOTENAME(@orderByColumn); | |
END | |
IF @orderByColumn IS NOT NULL | |
BEGIN | |
-- Construct the dynamic DELETE statement using a Common Table Expression (CTE). | |
-- This identifies all rows beyond the first 5000 and deletes them. | |
SET @sql = ' | |
;WITH RowsToDelete AS ( | |
SELECT ROW_NUMBER() OVER(ORDER BY ' + QUOTENAME(@orderByColumn) + ' ASC) AS RowNum | |
FROM ' + @fullTableName + ' | |
) | |
DELETE FROM RowsToDelete WHERE RowNum > 5000; | |
'; | |
BEGIN TRY | |
-- Execute the delete | |
EXEC sp_executesql @sql; | |
PRINT ' -> Successfully deleted rows. ' + CONVERT(NVARCHAR, @@ROWCOUNT) + ' rows affected.'; | |
END TRY | |
BEGIN CATCH | |
PRINT ' -> ERROR trimming table ' + @fullTableName + ': ' + ERROR_MESSAGE(); | |
END CATCH | |
END | |
ELSE | |
BEGIN | |
-- This case should be rare, only happening for tables with no columns. | |
PRINT ' -> ERROR: Could not determine a column to order by. Skipping table.'; | |
END | |
PRINT '----------------------------------------------------------------'; | |
FETCH NEXT FROM table_cursor INTO @schemaName, @tableName; | |
END; | |
CLOSE table_cursor; | |
DEALLOCATE table_cursor; | |
PRINT '================================================================'; | |
PRINT 'Data trim process finished.'; | |
PRINT 'RECOMMENDATION: You should now shrink the database files to reclaim disk space.'; | |
GO |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment