7

Если вы настроили столбец таблицы как вычисленный столбец, Формула которого вызывает функцию, становится больно изменять эту базовую функцию. При каждом изменении вы должны найти каждый столбец, Формула которого ссылается на функцию, удалить ссылку, сохранить таблицу, изменить функцию, добавить все обратно и снова сохранить. Даже небольшие изменения - кошмары.Функция Alter SQL, на которую ссылается вычисляемая колонка

Можете ли вы рассказать SQL Server, что вам не важно, что функция ссылается на Формулы и просто пойти дальше и изменить базовую функцию?

Дополнительная информация: Вычисленный столбец не сохраняется или не ссылается на ограничение FK, поскольку оно не является детерминированным. Функция учитывает текущее время. Это касается вопроса о том, истек срок записи или нет.

+0

Я согласен, что это БОЛЬШАЯ боль! Чувствую это прямо сейчас! –

+0

У меня такая же проблема.Я предполагаю, что есть веская причина, почему MS SQL не позволяет этого, но тем не менее, его реальная боль (+1 для общего горя) –

ответ

5

Нет, насколько я знаю, вы не можете этого сделать - вам сначала нужно удалить все вычисленные столбцы, ссылающиеся на функцию, изменить функцию, а затем воссоздать вычисленные столбцы.

Может быть, MS даст нам команду «CREATE ИЛИ ALTER FUNCTION» в SQL Server 2010/2011? :-)

Marc

+0

Ну, я полагаю, вы просто не можете этого сделать. И это то, что вы сказали, и вы сказали это в первую очередь. – colithium

+0

Действительно? Не могли бы вы просто удалить ограничение из столбца, а затем изменить функцию, а затем повторно применить ограничение? –

0

Вы можете попробовать с некоторой хорошей схемой инструмента для сравнения, что создать сценарий для вас :)

+0

У меня SQL Compare 8 и damn, если я могу найти команду меню для этого ... – jcollum

4

Последствия альтера может быть огромным.

Вы проиндексировали столбцы? Использовал его в представлении с schemabinding? Сохраняли его? Внешняя связь с ним?

Что делать, если ALTER изменяет тип данных, NULLability или детерминизм?

Легче остановить ALTER FUNCTION с зависимостями, чем справляться со многими сценариями.

+0

Функция зависит от времени и не может быть сохранена. По той же причине у него не может быть ограничения FK (хотя столбец ALLWAYS является допустимым значением, ссылающимся на PK другой таблицы). – colithium

+0

Это * ваша * функция, а не общий случай. Что лучше: неуклонно запрещать ALTER FUNCTION с зависимостями или допускать это в значительной степени случайным образом? – gbn

+0

Моя функция не является чем-то особенным, это происходит из-за того, что она не детерминирована. Я уточнил, что в моем вопросе с редактированием. Не должно быть никаких негативных последствий, вызванных изменением недетерминированных функций. Но возможно ли это? – colithium

0

Вы можете изменить колонку, которая не вычисляется, и обновить ее с помощью TRIGGER.

Или вы можете переименовать таблицу в другое место, вынуть вычисляемый столбец и создать VIEW вместо исходной таблицы (т. Е. С именем исходной таблицы) и включить нужный столбец.

EDIT: обратите внимание, что это может испортиться с вашими INSERT в исходное имя таблицы (теперь VIEW). Очевидно, что вы можете сохранить старую таблицу, вынуть вычисляемый столбец и создать отдельный VIEW, содержащий вычисленный столбец.

Нам приходилось много работать над вычисленными столбцами, чтобы решить, что они больше проблем, чем получают. Fail-saf inserts (1), пытаясь вставить в VIEW на таблицы с вычисленными столбцами, вещи, которые требуют возиться с SET ARITHABORT и так далее.

(1) Мы отказоустойчивых вставки нравится:

INSERT INTO MyTable SELECT * FROM MyOtherTable WHERE ...

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

+0

Это то, что значение вычисленного столбца не является детерминированным. Смысл, если вы спросите его, что это такое, он может сказать одно, а затем через секунду после абсолютно никаких изменений данных, он может сказать что-то другое. Триггеры здесь не работают. – colithium

+0

Я читал, что сказал, что он не детерминирован, мой ум тогда блуждал! Извини за это. – Kristen

1

Предположим таблицу T1 с колоннами С1, С2, С3, С4, С5, где С4 представляет собой вычисляемый столбец

Также предположим, что С4 ссылки функционируют OldFunc, которые вы хотите быть заменен NewFunc

Во-первых, Перемещение без вычисляемых столбцов из всех строк в таблице темп

Select C1, C2, C3, C5 into TmpT1 from T1 
Go 

Далее, Удалить все строки из T1

Delete From T1 
go 

Теперь Вы можете изменить столбец C4

Alter table T1 alter column C4 as dbo.NewFunc() 
Go 

Теперь поместите сохраненные данные обратно в исходную таблицу

Insert Into T1 (C1,C2,C3,C5) select C1,C2,C3,C5 from TmpT1 

Теперь удалите Temp Таблица

Drop Table TmpT1 
2

Извините за столь поздний ответ, но это может быть полезно.

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

Пример:
Вычисленное колонки используют следующую формулу: dbo.link_comp («123»)
Эта функция вперед, аргументы и вызовы и возвращают функцию dbo.link («123») (Ваша действительная функция)
Обе функции просто должны использовать те же аргументы и возвращать один и тот же тип.

Тогда функция, которая заблокирована, - dbo.link_comp, и вы все еще можете использовать ALTER dbo.link.
Кроме того, если ваша функция вызывается из другого SQL, вы все равно можете использовать свое реальное имя функции dbo.link, фиктивная функция dbo.link_comp предназначена только для вычисленного столбца.

0

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

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

Если вам нужно внести изменения в параметры в определениях (например, мне нужно), вы можете просто скомпоновать эту часть, в которой снова создаются определения.

Если у вас есть расчетные столбцы внутри индексов или других потребностей, вы можете легко расширить код, но это выходит за рамки моих потребностей.

Надеюсь, это может быть полезно кому-то еще.

/* Create temporary table to hold definitions */ 
CREATE TABLE [#FUNCTION] 
(
    [TABLE_NAME] nvarchar(255) NOT NULL, 
    [COLUMN_NAME] nvarchar(255) NOT NULL, 
    [DEFINITION] nvarchar(255) NOT NULL 
) 
GO 

/* Add data to temp table */ 
INSERT INTO [#FUNCTION] ([TABLE_NAME], [COLUMN_NAME], [DEFINITION]) 
SELECT TABLE_NAME, COLUMN_NAME, definition FROM INFORMATION_SCHEMA.COLUMNS 
INNER JOIN sys.computed_columns ON (object_id = object_id(TABLE_NAME) AND name = COLUMN_NAME) 
WHERE definition LIKE '%MyFunctionName%' 
GO 

/* Remove columns */ 
DECLARE @TABLE_NAME nvarchar(255) 
DECLARE @COLUMN_NAME nvarchar(255) 

DECLARE c_CursorName CURSOR LOCAL FOR SELECT [TABLE_NAME], [COLUMN_NAME] FROM [#FUNCTION] 
OPEN c_CursorName 

FETCH NEXT FROM c_CursorName INTO @TABLE_NAME, @COLUMN_NAME 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    EXEC('ALTER TABLE [' + @TABLE_NAME + '] DROP COLUMN [' + @COLUMN_NAME + ']') 

    FETCH NEXT FROM c_CursorName INTO @TABLE_NAME, @COLUMN_NAME 
END 

CLOSE c_CursorName 
DEALLOCATE c_CursorName 
GO 

/* Update function */ 
-- Update function here 
GO 

/* Recreate computed columns */ 
DECLARE @TABLE_NAME nvarchar(255) 
DECLARE @COLUMN_NAME nvarchar(255) 
DECLARE @DEFINITION nvarchar(255) 

DECLARE c_CursorName CURSOR LOCAL FOR SELECT [TABLE_NAME], [COLUMN_NAME], [DEFINITION] FROM [#FUNCTION] 
OPEN c_CursorName 

FETCH NEXT FROM c_CursorName INTO @TABLE_NAME, @COLUMN_NAME, @DEFINITION 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    EXEC('ALTER TABLE [' + @TABLE_NAME + '] ADD [' + @COLUMN_NAME + '] AS ' + @DEFINITION) 

    FETCH NEXT FROM c_CursorName INTO @TABLE_NAME, @COLUMN_NAME, @DEFINITION 
END 

CLOSE c_CursorName 
DEALLOCATE c_CursorName 
GO 

/* Remove temp table */ 
DROP TABLE [#FUNCTION] 
GO 
Смежные вопросы