문제

공식이 함수를 호출하는 계산 된 열로 테이블 열을 설정하면 기본 기능을 변경하는 것이 고통이됩니다. 모든 변경 사항에 따라 함수를 참조하고 참조를 제거하고 테이블을 저장하고 기능을 변경하고 모든 것을 다시 추가하고 다시 저장하는 모든 단일 열을 찾아야합니다. 작은 변화조차도 악몽입니다.

SQL Server에 함수가 공식에 의해 참조되고 기본 기능을 변경하는 것을 신경 쓰지 않는다고 말할 수 있습니까?

추가 세부 사항 : 계산 된 열은 FK 제약 조건이 비 결정적이기 때문에 FK 제약 조건에 의해 지속되거나 참조되지 않습니다. 이 기능은 현재 시간을 고려합니다. 기록이 만료되었는지 아닌지에 대한 질문을 다루고 있습니다.

도움이 되었습니까?

해결책

아니요, 내가 아는 한, 당신은 이것을 할 수 없습니다 - 먼저 기능을 참조하는 모든 계산 열을 제거하고, 함수를 변경 한 다음, 계산 된 열을 재현해야합니다.

SQL Server 2010/2011에서 MS가 "Create 또는 Alter Function"명령을 제공할까요? :-)

마크

다른 팁

변경의 결과는 엄청날 수 있습니다.

열을 인덱싱 했습니까? Schemabinding과 함께 사용 했습니까? 지속 되었습니까? 그것에 대한 외국의 주요 관계?

Alter가 데이터 유형, 무효 성 또는 결정론을 변경하면 어떻게됩니까?

많은 시나리오를 다루는 것보다 종속성으로 변경 기능을 중지하는 것이 더 쉽습니다.

이 늦은 답변에 대해 죄송하지만 유용 할 수 있습니다.

실제 기능을 호출하는 각 계산 열에 더미 기능을 사용할 수 있습니다.

예시:
계산 된 열은 공식을 사용합니다 : dbo.link_comp ( '123')
이 함수는 인수와 호출을 전달하고 함수 dbo.link ( '123') (실제 함수)를 반환합니다.
두 기능 모두 동일한 인수를 사용하고 동일한 유형을 반환하면됩니다.

그런 다음 잠겨있는 함수는 dbo.link_comp이며 여전히 dbo.link를 변경할 수 있습니다.
또한 다른 SQL에서 기능이 호출되는 경우 실제 기능 이름 DBO.Link를 사용할 수 있습니다. 더미 함수 DBO.link_comp는 계산 된 열에 대해서만 가능합니다.

C1, C1, C2, C3, C4, C5가있는 표 T1을 가정합니다. 여기서 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

좋은 스키마 비교 도구를 사용하여 스크립트를 만들 수 있습니다. :)

열을 컴퓨팅하지 않도록 변경하고 트리거로 업데이트 할 수 있습니다.

또는 테이블의 이름을 다른 것으로 바꾸고, 계산 된 열을 떨어 뜨린 후, 원래 테이블 대신 (예 : 원래 테이블 이름의)와 필요한 "계산 된"열을 포함하여보기를 만들 수 있습니다.

편집 : 이것은 삽입물을 원래 테이블 이름으로 엉망으로 만들 수 있습니다 (현재보기). 분명히 오래된 테이블을 유지하고 계산 된 열을 떨어 뜨린 다음 계산 된 열이 포함 된 별도의보기를 만들 수 있습니다.

우리는 그들이 얻는 것보다 더 많은 어려움이라고 결정하기 위해 계산 된 열을 충분히 일해야했습니다. Fail-SAF Inserts (1), 계산 된 열, 세트 Arithabort를 엉망으로 만드는 것 등을 사용하여 테이블에보기에 삽입하려고합니다.

(1) 우리는 다음과 같은 실패 안전 삽입물이 있습니다.

mytable select *에 삽입 *에서 MyOthertable에서 ...

새 열이 하나의 테이블을 추가하고 다른 테이블이 아닌 경우 실패하도록 설계되었습니다. 계산 된 열을 사용하면 모든 열을 명시 적으로 이름을 지정해야합니다. 이는 해당 안전망을 잃게됩니다.

나는 이것이 파티에 늦었다는 것을 알고 있지만 오늘 같은 문제를 겪고 있었고 실제로 문제를 해결하는 것은 찾지 못했기 때문에 빠르게 스크립팅했습니다.

기본적으로 함수를 사용하여 계산 된 각 열에 대한 열 정보를 고정하는 임시 테이블을 만듭니다. 테이블에서 열을 떨어 뜨립니다. 그런 다음 기능을 업데이트하고 정의로 모든 열을 다시 재현하도록합니다.

정의 내에서 매개 변수를 변경 해야하는 경우 (필요한 것과 같이) 정의가 다시 생성되는 위치로 해당 부분을 스크립트 할 수 있습니다.

인덱스 또는 기타 요구 사항 내에서 열을 계산 한 경우 코드를 쉽게 확장 할 수 있지만 이는 내 요구의 범위를 벗어났습니다.

다른 사람에게 유용 할 수 있기를 바랍니다.

/* 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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top