Как удалить, ALTER, а затем воссоздать любые объекты базы данных, которые обращаются к столбцу с помощью SQL? - PullRequest
0 голосов
/ 16 ноября 2018

У меня есть гигантская старая устаревшая база данных SQL Server. Я пытаюсь изменить каждое значение datetime на datetime2, но простой подход (циклический скрипт TSQL с использованием курсора) позволяет решить множество проблем:

Сообщение 5074, Уровень 16, Состояние 1, Строка 1
Индекс 'IX_Table_ColId_ModifiedOn' зависит от столбца 'ModifiedOn'

Сообщение 4922, Уровень 16, Состояние 9, Строка 1
ALTER TABLE ALTER COLUMN ModifiedOn не выполнен, так как один или несколько объектов имеют доступ к этому столбцу.

Помимо индексов, есть вычисляемые столбцы, ограничения по умолчанию и другие вещи, которые используют эти столбцы, блокируя ALTER.

Предотвращение простоев для нас не проблема. Существует ли магический сценарий или метод TSQL, который может просто найти объекты, связанные с столбцом / таблицей, временно удалить их, разрешить ALTER, а затем воссоздать их?

Похожие вопросы:

1 Ответ

0 голосов
/ 17 ноября 2018

Я думаю, что вы можете попробовать найти все таблицы, в которых есть столбцы с типом данных 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

Вероятно, есть лучший способ сделать последнюю часть, как только вы получите данные, я позволю вам сделать это. Надеюсь, это поможет.

...