PlusMagi's Blog By Pitt Phunsanit SQL Server MSSQL: Batch Alter Table Drop Columns

MSSQL: Batch Alter Table Drop Columns

ตัวอย่าง batch script alter drop column หลาย ๆ column ออกจาก table ในครั้งเดียว และ
batch_alter_table_drop_columns.sql

-- USE DB_DEV;
-- USE DB_QA;
-- USE DB_SIT;
-- USE DB_PRO; -- 1. Configuration
DECLARE @SchemaName AS NVARCHAR (128) = N'PItt';
DECLARE @TableName AS NVARCHAR (128) = N'Phunsanit'; -- 2. stop scrip if column not null and empty
DECLARE @StopScript BIT = 0; -- flag to stop the script -- 3. Variables for the script
DECLARE @FullTableName NVARCHAR (257) ;
DECLARE @TableObjectID INT;
DECLARE @CurrentColumnName NVARCHAR (128) ;
DECLARE @SqlStatement NVARCHAR (MAX) ;
DECLARE @HasData BIT = 0;
DECLARE @CheckSql NVARCHAR (MAX) ;
DECLARE @CheckParams NVARCHAR (100) = N'@HasData BIT OUTPUT';
DECLARE @DataTypeName NVARCHAR (128) ; -- <-- NEW: To store the column's data type -- 4. Define the list of columns you want to drop
DECLARE @ColumnsToDrop TABLE (ColumnName NVARCHAR (128) PRIMARY KEY) ; INSERT INTO @ColumnsToDrop (ColumnName) VALUES (N'created_at') , (N'created_by') , (N'deleted_at') , (N'deleted_by') , (N'updated_at') , (N'updated_by') , -- 5. Store the actual commands to run (if checks pass) DECLARE @CommandsToRun TABLE (SqlStatement NVARCHAR (MAX) , ColumnName NVARCHAR (128)) ; -- 6. Safety Check: Stop if the table itself doesn't exist
SET @FullTableName = QUOTENAME (@SchemaName) + '.' + QUOTENAME (@TableName) ;
SET @TableObjectID = OBJECT_ID (@FullTableName) ; IF @TableObjectID IS NULL
BEGIN PRINT 'Error: The table ' + @FullTableName + ' does not exist. Halting script.'; RETURN; -- Stops the script
END PRINT '--- PRE-CHECK ---';
PRINT 'Checking columns on table: ' + @FullTableName; -- 7. Create a cursor to loop through and check each column
DECLARE col_cursor CURSOR FOR
SELECT ColumnName FROM @ColumnsToDrop; OPEN col_cursor; FETCH NEXT FROM col_cursor INTO @CurrentColumnName; -- 8. First Loop (Pre-Check) WHILE @@FETCH_STATUS = 0
BEGIN SET @HasData = 0; -- Reset flag for each column -- Check if the column exists on this specific table IF EXISTS (SELECT 1 FROM sys.columns c WHERE c.object_id = @TableObjectID AND c.name = @CurrentColumnName) BEGIN -- *** MODIFIED BLOCK *** -- First, get the column's data type SELECT @DataTypeName = ty.name FROM sys.columns c JOIN sys.types ty ON c.user_type_id = ty.user_type_id WHERE c.object_id = @TableObjectID AND c.name = @CurrentColumnName; -- Now build the data check SQL based on the type IF @DataTypeName IN (N'varchar', N'nvarchar', N'char', N'nchar', N'text', N'ntext') BEGIN -- For string types, check for NOT NULL AND not empty string (your request) -- This means NULLs or '' (empty strings) are OK to drop SET @CheckSql = N'SELECT TOP 1 @HasData = 1 FROM ' + @FullTableName + N' WHERE ' + QUOTENAME (@CurrentColumnName) + N' IS NOT NULL' + N' AND ' + QUOTENAME (@CurrentColumnName) + N' != '''''; -- '''' is an escaped ' PRINT ' [INFO] Column ' + QUOTENAME (@CurrentColumnName) + ' is a string. Checking for data (not NULL and not '''') .'; END ELSE BEGIN -- For non-string types (int, datetime, etc.) , just check for NOT NULL SET @CheckSql = N'SELECT TOP 1 @HasData = 1 FROM ' + @FullTableName + N' WHERE ' + QUOTENAME (@CurrentColumnName) + N' IS NOT NULL'; PRINT ' [INFO] Column ' + QUOTENAME (@CurrentColumnName) + ' is not a string. Checking for data (not NULL) .'; END -- Run the dynamic check EXEC sp_executesql @CheckSql, @CheckParams, @HasData = @HasData OUTPUT; -- *** END OF MODIFIED BLOCK *** IF @HasData = 1 BEGIN -- Data found! Mark the script to stop. PRINT ' [ERROR] Column ' + QUOTENAME (@CurrentColumnName) + ' contains data. Script will be stopped.'; SET @StopScript = 1; END ELSE BEGIN -- Column is empty (all NULL or '') . It is safe to drop. PRINT ' [OK] Column ' + QUOTENAME (@CurrentColumnName) + ' is empty. Queued for drop.'; -- Add the drop command to our queue SET @SqlStatement = N'ALTER TABLE ' + @FullTableName + N' DROP COLUMN ' + QUOTENAME (@CurrentColumnName) ; INSERT INTO @CommandsToRun (SqlStatement, ColumnName) VALUES (@SqlStatement, @CurrentColumnName) ; END END ELSE BEGIN -- Column does not exist, so skip it PRINT ' [INFO] Column ' + QUOTENAME (@CurrentColumnName) + ' (does not exist) . Skipping.'; END -- Get the next column from the list FETCH NEXT FROM col_cursor INTO @CurrentColumnName;
END; -- 9. Clean up the check cursor
CLOSE col_cursor;
DEALLOCATE col_cursor; -- 10. THE "STOP" CHECK
PRINT '---';
IF @StopScript = 1
BEGIN PRINT 'Execution HALTED. One or more columns contained data (see [ERROR] messages above) .'; PRINT 'No columns were dropped.'; RETURN; -- This is the STOP you requested
END -- 11. Execution (only runs if @StopScript is still 0) PRINT 'All checks passed. Proceeding with drop operations...'; DECLARE exec_cursor CURSOR FOR
SELECT SqlStatement, ColumnName FROM @CommandsToRun; OPEN exec_cursor; FETCH NEXT FROM exec_cursor INTO @SqlStatement, @CurrentColumnName; WHILE @@FETCH_STATUS = 0
BEGIN BEGIN TRY EXEC sp_executesql @SqlStatement; PRINT ' Successfully dropped column: ' + QUOTENAME (@CurrentColumnName) ; END TRY BEGIN CATCH PRINT ' ERROR: Could not drop column ' + QUOTENAME (@CurrentColumnName) + '. Please check dependencies (indexes, constraints) .'; PRINT ' Error Message: ' + ERROR_MESSAGE () ; END CATCH FETCH NEXT FROM exec_cursor INTO @SqlStatement, @CurrentColumnName;
END; -- 12. Clean up the execution cursor
CLOSE exec_cursor;
DEALLOCATE exec_cursor; PRINT 'Column drop process complete.';

ป้ายกำกับ:, , , ,