Files
DBAdmin/Part3.sql
T
2026-06-24 08:30:19 +00:00

186 lines
6.2 KiB
Transact-SQL

-- ======================================================
-- DYNAMIC COLUMN DATA TYPE UPDATE SCRIPT (v3)
-- ======================================================
SET XACT_ABORT ON;
SET NOCOUNT ON;
SET LOCK_TIMEOUT 5000; -- avoid hanging forever on busy objects
------------------------------------------------------------
-- CONFIGURATION
------------------------------------------------------------
DECLARE @NewDataType NVARCHAR(100) = 'Varchar(9)'; -- <-- Target datatype
DECLARE @ColumnPattern NVARCHAR(100) = '%DUN%'; -- <-- Column/Parameter pattern
DECLARE @DryRun BIT = 0 --1 is for print, 0 is for execute
------------------------------------------------------------
------------------------------------------------------------
-- END STEP 6 FIX
------------------------------------------------------------
-- ===============================
-- STEP 4: ALTER TABLE COLUMNS
-- ===============================
DECLARE @Schema SYSNAME;
DECLARE @Table SYSNAME;
DECLARE @Column SYSNAME;
DECLARE @OldDataType NVARCHAR(128);
DECLARE @AlterSQL NVARCHAR(MAX);
DECLARE @IsNullable BIT; -- track nullability
DECLARE colCur CURSOR LOCAL FAST_FORWARD FOR
SELECT DISTINCT
PARSENAME(ObjectName, 2) AS SchemaName,
PARSENAME(ObjectName, 1) AS TableName,
ColumnName,
ColumnDataType
FROM DBO.TEMP2
WHERE ObjectType = 'TABLE';
OPEN colCur;
FETCH NEXT FROM colCur INTO @Schema, @Table, @Column, @OldDataType;
WHILE @@FETCH_STATUS = 0
BEGIN
BEGIN TRY
-- ====================================================
-- ? Check if column is currently NOT NULL
-- so we can preserve it after datatype change
-- If original was NOT NULL ? keep NOT NULL
-- If original was NULL ? keep NULL
-- Without this PK columns become nullable
-- and PK recreation fails
-- ====================================================
SELECT @IsNullable = c.is_nullable
FROM sys.columns c
JOIN sys.tables t
ON t.object_id = c.object_id
JOIN sys.schemas s
ON s.schema_id = t.schema_id
WHERE s.name = @Schema
AND t.name = @Table
AND c.name = @Column;
-- ? Build ALTER COLUMN with correct nullability
SET @AlterSQL = 'ALTER TABLE ' + QUOTENAME(@Schema) + '.' + QUOTENAME(@Table) +
' ALTER COLUMN ' + QUOTENAME(@Column) + ' ' + @NewDataType +
-- ? Preserve NOT NULL if column was NOT NULL
CASE WHEN @IsNullable = 0
THEN ' NOT NULL'
ELSE ' NULL'
END;
IF @DryRun = 1
INSERT INTO MyprintLog (LogMessage, LogDate)
VALUES (@AlterSQL, SYSDATETIME());
ELSE
BEGIN
PRINT 'Attempting ALTER TABLE: ' + @AlterSQL;
EXEC sys.sp_executesql @AlterSQL;
insert into dbo.result(objecttype, objectname,ColumnName,ColumnDataType)
VALUES('Table',@Table,@Column,@NewDataType)
INSERT INTO MyprintLog (LogMessage, LogDate)
VALUES (@AlterSQL, SYSDATETIME());
END
END TRY
BEGIN CATCH
DECLARE @CatchMsg5 NVARCHAR(MAX) = ERROR_MESSAGE();
DECLARE @CatchXact5 SMALLINT = XACT_STATE();
DECLARE @CatchObjName5 NVARCHAR(512) = @Schema + '.' + @Table;
PRINT '=== ERROR [ALTER_COLUMN] === MSG: ' + @CatchMsg5;
IF @CatchXact5 = -1
ROLLBACK TRANSACTION;
EXEC dbo.usp_LogError
@Step = 'ALTER_COLUMN',
@ObjectType = 'TABLE',
@ObjectName = @CatchObjName5,
@ColumnName = @Column,
@ColumnDataType = @OldDataType,
@ErrorMessage = @CatchMsg5,
@SqlStatement = @AlterSQL,
@XactState = @CatchXact5;
--THROW;
END CATCH
FETCH NEXT FROM colCur INTO @Schema, @Table, @Column, @OldDataType;
END
CLOSE colCur;
DEALLOCATE colCur;
PRINT '--- RECREATING SCHEMA-BOUND VIEWS ---';
-- ===============================
-- Recreating schema bound views
-- ===============================
DECLARE @CreateSQL2 NVARCHAR(MAX);
DECLARE @OBJNAME NVARCHAR(MAX)
DECLARE curCreate1 CURSOR FAST_FORWARD FOR
SELECT createscript, ViewFullName
FROM SchemaBoundViews ;
OPEN curCreate1;
FETCH NEXT FROM curCreate1 INTO @CreateSQL2,@OBJNAME;
PRINT '--- RECREATING SCHEMA-BOUND VIEWS ---';
WHILE @@FETCH_STATUS = 0
BEGIN
begin try
PRINT 'Creating view:';
SET @CreateSQL2 = SUBSTRING(
@CreateSQL2,
CHARINDEX('CREATE VIEW', UPPER(@CreateSQL2)),
LEN(@CreateSQL2)
);
-- ? Convert to CREATE OR ALTER so it works whether view exists or not
SET @CreateSQL2 = REPLACE(@CreateSQL2, 'CREATE VIEW', 'CREATE OR ALTER VIEW');
PRINT '--- RECREATING SCHEMA-BOUND VIEWS ---';
IF @DryRun = 1
INSERT INTO MyprintLog (LogMessage, LogDate)
VALUES (CONCAT('-- DRYRUN ALTERING ', @OBJNAME, ' ',
@CreateSQL2), SYSDATETIME());
ELSE
PRINT '== [RECREATE_SCHEMABOUNDVIEWS] === MSG: '+@OBJNAME
EXEC sys.sp_executesql @CreateSQL2;
INSERT INTO MyprintLog (LogMessage, LogDate)
VALUES ('== [RECREATE_SCHEMABOUNDVIEWS] === MSG: '+@OBJNAME, SYSDATETIME());
END TRY
BEGIN CATCH
DECLARE @CatchMsg10 NVARCHAR(MAX) = ERROR_MESSAGE();
DECLARE @CatchXact10 SMALLINT = XACT_STATE();
PRINT '=== ERROR [RECREATE_SCHEMABOUNDVIEWS] === MSG: ' + @CatchMsg10;
IF @CatchXact10 <> -1
EXEC dbo.usp_LogError
@Step = 'RECREATE_OBJECT',
@ObjectType = 'SCHEMABOUNDVIEWS',
@ObjectName = @OBJNAME,
@ColumnName = NULL,
@ColumnDataType = NULL,
@ErrorMessage = @CatchMsg10,
@SqlStatement = @CreateSQL2,
@XactState = @CatchXact10;
--THROW;
END CATCH;
FETCH NEXT FROM curCreate1 INTO @CreateSQL2,@OBJNAME;
END
CLOSE curCreate1;
DEALLOCATE curCreate1;