Jun 24, 2026, 10:30 AM
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
-- ======================================================
|
||||
-- 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;
|
||||
|
||||
Reference in New Issue
Block a user