首页 > 解决方案 > 如何删除、更改、然后重新创建使用 SQL 访问列的任何数据库对象?

问题描述

我有一个巨大的旧式 SQL Server 数据库。我正在尝试将 every 更改datetimedatetime2,但简单的方法(使用游标的循环 TSQL 脚本)遇到了许多这样的问题:

消息 5074,级别 16,状态 1,第 1 行
索引“IX_Table_ColId_ModifiedOn”取决于列“ModifiedOn”

消息 4922,级别 16,状态 9,第 1 行
ALTER TABLE ALTER COLUMN ModifiedOn 失败,因为一个或多个对象访问此列。

除了索引之外,还有计算列、默认约束和其他使用这些列的东西,从而阻塞了 ALTER。

避免停机对我们来说不是问题。是否有一个神奇的 TSQL 脚本或技术可以找到连接到列/表的东西,暂时删除它们,允许 ALTER,然后重新创建它们?

相关问题:

标签: sqlsql-servertsqlsql-server-2016

解决方案


我认为您可以尝试查找所有具有DATETIME数据类型列的表,以及它们是否具有任何索引。请考虑以下几点:

create table #TempTable (
TableName VARCHAR(MAX),
ColumnName VARCHAR(MAX),
IndexName VARCHAR(MAX)
)

;WITH CTE1(TableName, ColumnName) AS
(
    SELECT
        so.name table_name
       ,sc.name column_name
    from sysobjects so
    inner join syscolumns sc on (so.id = sc.id)
    inner join systypes st on (st.type = sc.type)
    where so.type = 'U'
    and st.name IN ('DATETIME')
),
CTE2(TABLEName, ColumnName, IndexName) AS
(
           SELECT cte1.TableName, c.name, i.name
    FROM    sys.index_columns AS ic
            INNER JOIN sys.indexes AS i
                ON ic.[object_id] = i.[object_id]
                AND ic.index_id = i.index_id
            INNER JOIN sys.columns AS c
                ON ic.[object_id] = c.[object_id]
                AND ic.column_id = c.column_id
            INNER JOIN cte1 AS cte1 ON cte1.columnName = c.name


)
INSERT INTO #TempTable
SELECT DISTINCT * FROM CTE2

SELECT * FROM #TempTable

然后您可以执行一些动态 SQL 来执行以下操作:

--Dynamic SQL populate values

    BEGIN
        -- drop index
        -- alter column 
        -- delete row from temp table
        -- recreate index
        -- process next row

    END

一旦你得到数据,可能有更好的方法来完成最后一部分,我会让你去做。希望这可以帮助。


推荐阅读