-- Alters all columns in all Tables in the database to allow NULLs (Excludes all Primary Keys) DECLARE @sqlaltertable NVARCHAR(MAX) = N'' DECLARE @i int = 1 DECLARE @count int DECLARE @objectid int DECLARE @object NVARCHAR(500) = N'' --Create Source List temp table CREATE TABLE #SourceList ( [Id] [int] IDENTITY(1,1) NOT NULL, [ObjectId] [int] NOT NULL ) --insert into table #SourceList INSERT INTO #SourceList SELECT distinct tb.[OBJECT_ID] FROM SYS.COLUMNS C INNER JOIN SYS.TABLES tb ON tb.[object_id] = C.[object_id] INNER JOIN SYS.TYPES T ON C.system_type_id = T.user_type_id WHERE C.is_nullable = 0 AND C.is_identity = 0 AND tb.[type] = 'U' SET @count = @@ROWCOUNT --Create index for the temp table CREATE CLUSTERED INDEX #SourceList0 ON #SourceList ([Id],[ObjectId]) WHILE (@i <= @count) BEGIN SET @objectid = (SELECT [ObjectId] FROM #SourceList WHERE [Id] = @i) SET @object = (SELECT OBJECT_NAME (@objectid)) SELECT @sqlaltertable = @sqlaltertable +[sqlaltertable] FROM ( SELECT [sqlaltertable] = N' ALTER TABLE ' + QUOTENAME(SCHEMA_NAME(tb.[schema_id])) + '.' + QUOTENAME(OBJECT_NAME(tb.[OBJECT_ID])) + ' ALTER COLUMN ' + C.NAME + ' ' + CASE WHEN T.name IN ('bigint','bit','datetime','float','image','int','money','smalldatetime','smallint','text','tinyint','uniqueidentifier','xml') THEN T.name WHEN T.name IN ('char','nchar') THEN T.name + '(' + convert(varchar(5),C.max_length) + ')' WHEN T.name IN ('numeric') THEN T.name + '(' + convert(varchar(5),C.precision) + ',' + convert(varchar(5),C.scale)+ ')' WHEN T.name IN ('nvarchar','varchar','varbinary') AND C.max_length = -1 THEN T.name + '(max)' WHEN T.name IN ('nvarchar','varchar') AND C.max_length <> -1 THEN T.name + '(' + convert(varchar(5),C.max_length) + ')' WHEN T.name IN ('decimal') THEN '[dbo].[EXPCURRENCY]' WHEN T.name IN ('real') THEN '[dbo].[frlCurrencyRate]' END + ' NULL;' FROM SYS.COLUMNS C INNER JOIN SYS.TABLES tb ON tb.[object_id] = C.[object_id] INNER JOIN SYS.TYPES T ON C.system_type_id = T.user_type_id WHERE C.is_nullable = 0 AND C.is_identity = 0 and tb.[type] = 'U' and T.name IN ('bigint','bit','datetime','float','image','int','money','smalldatetime','smallint','text','tinyint','uniqueidentifier','xml','char','nchar','numeric','nvarchar','varchar','varbinary','decimal','real') and tb.object_id = @objectid and not exists ( SELECT object_id(CS.TABLE_SCHEMA + '.' + CS.TABLE_NAME) , k.COLUMN_NAME FROM information_schema.table_constraints AS CS INNER JOIN information_schema.key_column_usage AS K ON CS.table_name = K.table_name AND CS.constraint_catalog = K.constraint_catalog AND CS.constraint_schema = K.constraint_schema AND CS.constraint_name = K.constraint_name WHERE CS.constraint_type = 'PRIMARY KEY' and object_id(CS.TABLE_SCHEMA + '.' + CS.TABLE_NAME) = tb.[OBJECT_ID] and C.NAME = k.COLUMN_NAME) ) AS RA; BEGIN BEGIN TRY EXECUTE sp_executesql @sqlaltertable PRINT '['+@object+'] altered successfully' PRINT '' END TRY BEGIN CATCH DECLARE @ErrorMessage NVARCHAR(4000); DECLARE @ErrorSeverity INT; DECLARE @ErrorState INT; SELECT @ErrorMessage = ERROR_MESSAGE(), @ErrorSeverity = ERROR_SEVERITY(), @ErrorState = ERROR_STATE(); PRINT '***PROBLEM ALTERING TABLE***' PRINT '' RAISERROR (@ErrorMessage, -- Message text. @ErrorSeverity, -- Severity. @ErrorState -- State. ); END CATCH END SET @sqlaltertable = N'' SET @i = @i +1 END
Category: Useful Queries for Development
/* 5. Migrate TAT_TIME and CDT_DISB Tables (Specific Tables) Move data and indexes for all the TAT_TIME* and all the CDT_DISB* tables to the specified file group. Please take the latest backup and test this script before executing on the production database. Please check the values for the variables below. And first execute it in Debug Mode for quick testing. @NewFilegroup Name of the filegroup to which you'll be moving the clustered indexes. @Debug When set to "1", generates a script without actually moving anything. This can be used to preview what will be done. Setting this to "0" will cause this script to actually migrate the indexes. */ DECLARE @NewFilegroup nvarchar(100) = 'AdwentureWorksTimeDisb' DECLARE @Debug BIT = 0 DECLARE @id integer DECLARE @tbname nvarchar(100) DECLARE @indid integer DECLARE @indname nvarchar(100) DECLARE @fill integer DECLARE @unique VARCHAR(20) DECLARE @clustered VARCHAR(20) DECLARE @schema VARCHAR(20) DECLARE @column_list nvarchar(4000) DECLARE @include_list nvarchar(4000) DECLARE @strsql nvarchar(4000) DECLARE @crlf CHAR(2) = CHAR(13)+CHAR(10) IF @Debug = 1 PRINT 'Executing in Debug Mode Only.........' + @crlf + @crlf IF NOT EXISTS (SELECT 1 FROM sys.filegroups where name=@NewFilegroup) BEGIN RAISERROR('Filegroup [%s] does not exist. Aborting.', 10,1, @NewFilegroup) RETURN END declare curs1 cursor for SELECT t.object_id, t.name, i.index_id, i.name AS indname, CASE i.Fill_Factor WHEN 0 THEN 90 ELSE i.Fill_Factor END AS Fill_Factor, CASE i.Is_Unique WHEN 0 THEN '' WHEN 1 THEN ' UNIQUE ' END AS Is_Unique, CASE i.type_desc WHEN 'NONCLUSTERED' THEN '' WHEN 'CLUSTERED' THEN 'CLUSTERED' END AS Is_Clustered, s.name FROM sys.tables AS t INNER JOIN sys.schemas AS s ON t.schema_id = s.schema_id INNER JOIN sys.indexes AS i ON t.object_id = i.object_id WHERE t.type = 'U' AND (i.type_desc = 'NONCLUSTERED' OR i.type_desc = 'CLUSTERED') AND i.is_disabled = 0 AND (t.name LIKE 'TAT_TIME%' OR t.name LIKE 'CDT_DISB%') --Specific Tables ORDER BY t.name, i.name open curs1 fetch next from curs1 into @id,@tbname,@indid,@indname,@fill,@unique,@clustered,@schema while @@fetch_status=0 begin SET @Column_List='' SET @Include_List = '' SELECT @Column_List = @Column_List + CASE is_included_column WHEN 0 THEN '['+ c.name+'],' ELSE '' END, @Include_List = @Include_List + CASE is_included_column WHEN 1 THEN '['+ c.name+'],' ELSE '' END FROM sys.indexes i JOIN sys.objects o ON i.object_id = o.object_id JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id WHERE o.type = 'U' AND i.index_id = @indid AND o.object_id = @id ORDER BY ic.key_ordinal SET @Column_List=left(@Column_List,len(@Column_List)-1) IF LEN(@Include_List) > 0 BEGIN SET @Include_List = left(@Include_List,len(@Include_List)-1) SET @Include_List = ' INCLUDE ('+@Include_List+') ' END begin set @strsql = 'CREATE '+@Unique+ @clustered+' INDEX ['+@indname+'] ON ['+@schema+'].['+@tbname+']('+@Column_List+') '+@Include_List+' WITH (DROP_EXISTING=ON,FILLFACTOR = '+CONVERT(VARCHAR(5), @fill)+') ON ['+@NewFilegroup+']' IF @Debug=1 BEGIN print @strsql print '' END IF @Debug=0 BEGIN BEGIN TRY exec sp_executesql @strsql PRINT '['+@tbname+'].['+@indname+'] moved successfully' PRINT '' END TRY BEGIN CATCH DECLARE @ErrorMessage NVARCHAR(4000); DECLARE @ErrorSeverity INT; DECLARE @ErrorState INT; SELECT @ErrorMessage = ERROR_MESSAGE(), @ErrorSeverity = ERROR_SEVERITY(), @ErrorState = ERROR_STATE(); PRINT '***PROBLEM MIGRATING THIS INDEX***' PRINT '' RAISERROR (@ErrorMessage, -- Message text. @ErrorSeverity, -- Severity. @ErrorState -- State. ); END CATCH END end fetch next from curs1 into @id,@tbname,@indid,@indname,@fill,@unique,@clustered,@schema end close curs1 deallocate curs1
/* 4. Migrate Non Clustered Indexes Move non clustered indexes to the specified file group. Please take the latest backup and test this script before executing on the production database. Please check the values for the variables below. And first execute it in Debug Mode for quick testing. @NewFilegroup Name of the filegroup to which you'll be moving the clustered indexes. @Debug When set to "1", generates a script without actually moving anything. This can be used to preview what will be done. Setting this to "0" will cause this script to actually migrate the indexes. */ DECLARE @NewFilegroup nvarchar(100) = 'AdwentureWorksNonClustered' DECLARE @Debug BIT = 0 DECLARE @id integer DECLARE @tbname nvarchar(100) DECLARE @indid integer DECLARE @indname nvarchar(100) DECLARE @fill integer DECLARE @unique VARCHAR(20) DECLARE @schema VARCHAR(20) DECLARE @column_list nvarchar(4000) DECLARE @include_list nvarchar(4000) DECLARE @strsql nvarchar(4000) DECLARE @crlf CHAR(2) = CHAR(13)+CHAR(10) IF @Debug = 1 PRINT 'Executing in Debug Mode Only.........' + @crlf + @crlf IF NOT EXISTS (SELECT 1 FROM sys.filegroups where name=@NewFilegroup) BEGIN RAISERROR('Filegroup [%s] does not exist. Aborting.', 10,1, @NewFilegroup) RETURN END declare curs1 cursor for SELECT t.object_id, t.name, i.index_id, i.name AS indname, CASE i.Fill_Factor WHEN 0 THEN 90 ELSE i.Fill_Factor END AS Fill_Factor, CASE i.Is_Unique WHEN 0 THEN '' WHEN 1 THEN ' UNIQUE ' END AS Is_Unique, s.name FROM sys.tables AS t INNER JOIN sys.schemas AS s ON t.schema_id = s.schema_id INNER JOIN sys.indexes AS i ON t.object_id = i.object_id WHERE t.type = 'U' AND i.type_desc = 'NONCLUSTERED' AND i.is_disabled = 0 AND t.name NOT LIKE 'TAT_TIME%' AND t.name NOT LIKE 'CDT_DISB%' ORDER BY t.name, i.name open curs1 fetch next from curs1 into @id,@tbname,@indid,@indname,@fill,@unique,@schema while @@fetch_status=0 begin SET @Column_List='' SET @Include_List = '' SELECT @Column_List = @Column_List + CASE is_included_column WHEN 0 THEN '['+ c.name+'],' ELSE '' END, @Include_List = @Include_List + CASE is_included_column WHEN 1 THEN '['+ c.name+'],' ELSE '' END FROM sys.indexes i JOIN sys.objects o ON i.object_id = o.object_id JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id WHERE o.type = 'U' AND i.index_id = @indid AND o.object_id = @id ORDER BY ic.key_ordinal SET @Column_List=left(@Column_List,len(@Column_List)-1) IF LEN(@Include_List) > 0 BEGIN SET @Include_List = left(@Include_List,len(@Include_List)-1) SET @Include_List = ' INCLUDE ('+@Include_List+') ' END begin set @strsql = 'CREATE '+@Unique+' INDEX ['+@indname+'] ON ['+@schema+'].['+@tbname+']('+@Column_List+') '+@Include_List+' WITH (DROP_EXISTING=ON,FILLFACTOR = '+CONVERT(VARCHAR(5), @fill)+') ON ['+@NewFilegroup+']' IF @Debug=1 BEGIN print @strsql print '' END IF @Debug=0 BEGIN BEGIN TRY exec sp_executesql @strsql PRINT '['+@tbname+'].['+@indname+'] moved successfully' PRINT '' END TRY BEGIN CATCH DECLARE @ErrorMessage NVARCHAR(4000); DECLARE @ErrorSeverity INT; DECLARE @ErrorState INT; SELECT @ErrorMessage = ERROR_MESSAGE(), @ErrorSeverity = ERROR_SEVERITY(), @ErrorState = ERROR_STATE(); PRINT '***PROBLEM MIGRATING THIS INDEX***' PRINT '' RAISERROR (@ErrorMessage, -- Message text. @ErrorSeverity, -- Severity. @ErrorState -- State. ); END CATCH END end fetch next from curs1 into @id,@tbname,@indid,@indname,@fill,@unique,@schema end close curs1 deallocate curs1
/* 3. Migrate Heap Tables Move all heap tables to the specified file group Please take the latest backup and test this script before executing on the production database. Please check the values for the variables below. And first execute it in Debug Mode for quick testing. @NewFilegroup Name of the filegroup to which you'll be moving the clustered indexes. @Debug When set to "1", generates a script without actually moving anything. This can be used to preview what will be done. Setting this to "0" will cause this script to actually migrate the indexes. */ DECLARE @NewFilegroup nvarchar(100) = 'AdwentureWorksClustered' DECLARE @Debug BIT = 0 DECLARE @id integer DECLARE @tbname nvarchar(100) DECLARE @fill integer DECLARE @colname VARCHAR(20) DECLARE @schema VARCHAR(20) DECLARE @column_list nvarchar(4000) DECLARE @include_list nvarchar(4000) declare @strsql_ac nvarchar(4000) declare @strsql_ai nvarchar(4000) declare @strsql_m nvarchar(4000) declare @strsql_di nvarchar(4000) declare @strsql_dc nvarchar(4000) DECLARE @crlf CHAR(2) = CHAR(13)+CHAR(10) DECLARE @Filegroup nvarchar(100) = 'PRIMARY' IF @Debug = 1 PRINT 'Executing in Debug Mode Only.........' + @crlf + @crlf IF NOT EXISTS (SELECT 1 FROM sys.filegroups where name=@NewFilegroup) BEGIN RAISERROR('Filegroup [%s] does not exist. Aborting.', 10,1, @NewFilegroup) RETURN END SELECT DISTINCT object_id(c.TABLE_SCHEMA+'.'+c.TABLE_NAME) AS ObjectId, c.COLUMN_NAME AS colname INTO #Heapidentity FROM INFORMATION_SCHEMA.COLUMNS As c WHERE COLUMNPROPERTY(object_id(c.TABLE_SCHEMA+'.'+c.TABLE_NAME), c.COLUMN_NAME, 'IsIdentity') = 1 declare curs1 cursor for SELECT t.object_id, t.name, 90 AS Fill_Factor, s.name FROM sys.tables AS t INNER JOIN sys.schemas AS s ON t.schema_id = s.schema_id INNER JOIN sys.indexes AS i ON t.object_id = i.object_id LEFT JOIN #Heapidentity As h ON t.object_id = h.ObjectId WHERE t.type = 'U' AND i.type_desc = 'HEAP' AND i.is_disabled = 0 AND h.ObjectId IS NULL ORDER BY t.name open curs1 fetch next from curs1 into @id,@tbname,@fill,@schema while @@fetch_status=0 begin SET @Column_List='Id_heap_new' SET @Include_List = '' set @strsql_ac = 'ALTER TABLE ['+@schema+'].['+@tbname+'] ADD Id_heap_new Int Identity(1, 1)' set @strsql_ai = 'CREATE UNIQUE CLUSTERED INDEX ['+@tbname+'HeapMigrate] ON ['+@schema+'].['+@tbname+']('+@Column_List+') '+@Include_List+' WITH FILLFACTOR = '+CONVERT(VARCHAR(5), @fill)+' ON ['+@Filegroup+']' set @strsql_m = 'CREATE UNIQUE CLUSTERED INDEX ['+@tbname+'HeapMigrate] ON ['+@schema+'].['+@tbname+']('+@Column_List+') '+@Include_List+' WITH (DROP_EXISTING=ON,FILLFACTOR = '+CONVERT(VARCHAR(5), @fill)+') ON ['+@NewFilegroup+']' set @strsql_di = 'DROP INDEX ['+@tbname+'HeapMigrate] ON ['+@schema+'].['+@tbname+']' set @strsql_dc = 'ALTER TABLE ['+@schema+'].['+@tbname+'] DROP COLUMN Id_heap_new' IF @Debug=1 BEGIN print @strsql_ac print @strsql_ai print @strsql_m print @strsql_di print @strsql_dc print '' END IF @Debug=0 BEGIN BEGIN TRY exec sp_executesql @strsql_ac exec sp_executesql @strsql_ai exec sp_executesql @strsql_m exec sp_executesql @strsql_di exec sp_executesql @strsql_dc PRINT '['+@tbname+'] moved successfully' PRINT '' END TRY BEGIN CATCH DECLARE @ErrorMessage NVARCHAR(4000); DECLARE @ErrorSeverity INT; DECLARE @ErrorState INT; SELECT @ErrorMessage = ERROR_MESSAGE(), @ErrorSeverity = ERROR_SEVERITY(), @ErrorState = ERROR_STATE(); PRINT '***PROBLEM MIGRATING THIS INDEX***' PRINT '' RAISERROR (@ErrorMessage, -- Message text. @ErrorSeverity, -- Severity. @ErrorState -- State. ); END CATCH END fetch next from curs1 into @id,@tbname,@fill,@schema end close curs1 deallocate curs1 --------------------------------------------------------------------- declare curs2 cursor for SELECT t.object_id, t.name, 90 AS Fill_Factor, s.name, h.colname FROM sys.tables AS t INNER JOIN sys.schemas AS s ON t.schema_id = s.schema_id INNER JOIN sys.indexes AS i ON t.object_id = i.object_id INNER JOIN #Heapidentity As h ON t.object_id = h.ObjectId WHERE t.type = 'U' AND i.type_desc = 'HEAP' AND i.is_disabled = 0 ORDER BY t.name open curs2 fetch next from curs2 into @id,@tbname,@fill,@schema,@colname while @@fetch_status=0 begin SET @Include_List = '' set @strsql_ai = 'CREATE UNIQUE CLUSTERED INDEX ['+@tbname+'HeapMigrate] ON ['+@schema+'].['+@tbname+']('+@colname+') '+@Include_List+' WITH FILLFACTOR = '+CONVERT(VARCHAR(5), @fill)+' ON ['+@Filegroup+']' set @strsql_m = 'CREATE UNIQUE CLUSTERED INDEX ['+@tbname+'HeapMigrate] ON ['+@schema+'].['+@tbname+']('+@colname+') '+@Include_List+' WITH (DROP_EXISTING=ON,FILLFACTOR = '+CONVERT(VARCHAR(5), @fill)+') ON ['+@NewFilegroup+']' set @strsql_di = 'DROP INDEX ['+@tbname+'HeapMigrate] ON ['+@schema+'].['+@tbname+']' IF @Debug=1 BEGIN print @strsql_ai print @strsql_m print @strsql_di print '' END IF @Debug=0 BEGIN BEGIN TRY exec sp_executesql @strsql_ai exec sp_executesql @strsql_m exec sp_executesql @strsql_di PRINT '['+@tbname+'] moved successfully' PRINT '' END TRY BEGIN CATCH SELECT @ErrorMessage = ERROR_MESSAGE(), @ErrorSeverity = ERROR_SEVERITY(), @ErrorState = ERROR_STATE(); PRINT '***PROBLEM MIGRATING THIS INDEX***' PRINT '' RAISERROR (@ErrorMessage, -- Message text. @ErrorSeverity, -- Severity. @ErrorState -- State. ); END CATCH END fetch next from curs2 into @id,@tbname,@fill,@schema,@colname end close curs2 deallocate curs2