Функция изменения SQL, на которую ссылается вычисляемый столбец - PullRequest
8 голосов
/ 13 февраля 2009

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

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

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

Ответы [ 7 ]

6 голосов
/ 13 февраля 2009

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

Может быть, MS даст нам команду «СОЗДАТЬ ИЛИ ИЗМЕНИТЬ ФУНКЦИЮ» в SQL Server 2010/2011? : -)

Марк

4 голосов
/ 14 февраля 2009

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

Вы проиндексировали столбцы? Использовали его в представлении схемы? Сохранил это? Отношение внешнего ключа к нему?

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

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

3 голосов
/ 07 января 2015

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

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

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

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

1 голос
/ 28 апреля 2011

Предположим, таблица T1 со столбцами C1, C2, C3, C4, C5, где C4 - вычисляемый столбец

Также предположим, что функция ссылок C4 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

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

Drop Table TmpT1
0 голосов
/ 23 июня 2015

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

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

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

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

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

/* 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
0 голосов
/ 16 февраля 2009

Вы можете изменить столбец, чтобы он не был вычислен, и обновить его с помощью TRIGGER.

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

РЕДАКТИРОВАТЬ: обратите внимание, что это может помешать вашим ВСТАВКАМ в исходное имя таблицы (теперь ВИД). Очевидно, вы можете сохранить старую таблицу, удалить вычисляемый столбец и создать отдельный VIEW, содержащий вычисляемый столбец.

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

(1) У нас есть отказоустойчивые вставки, такие как:

Вставить в MyTable SELECT * ИЗ MyOtherTable ГДЕ ...

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

0 голосов
/ 13 февраля 2009

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

...