VS 환경에서는 항상 데이터베이스 프로젝트를 사용하여 업데이트 스크립트를 구현했습니다. 내 스크립트에는 "DatabaseUpdate17.sql"또는 "PriceUpdateFebruary2010.sql"과 같은 상상할 수없는 이름을 사용하는 경향이 있습니다. 그것들을 데이터베이스 프로젝트로 사용하면 팀 서버 작업, 버그 (그리고 코드 검토를 한 경우에도 버그)에 연결할 수 있습니다. 또한 각 데이터베이스 (권한이있는)에 스키마 변경 사항 수집을위한 테이블을 포함시킵니다.
CREATE TABLE [dbo].[AuditDDL](
[EventID] [int] IDENTITY(1,1) PRIMARY KEY NOT NULL,
[EventData] [xml] NULL, -- what did they do
[EventUser] varchar(100) NOT NULL, -- who did it
[EventTime] [datetime] DEFAULT (getdate()) -- when did they do it
)
GO
음, 그것은 6 Ws 중 3 개를 처리합니다 .
CREATE TRIGGER [trgAuditDDL]
ON DATABASE
FOR DDL_DATABASE_LEVEL_EVENTS
AS
INSERT INTO AuditDDL(EventData, EventUser)
SELECT EVENTDATA(), original_login()
GO
패치의 시작과 패치의 끝을 기록하는 insert 문을 포함합니다. 패치 외부에서 발생하는 이벤트는 살펴볼 것입니다.
예를 들어 "patch 17"에 대한 "begin patch"삽입은 다음과 같습니다.
INSERT INTO [dbo].[AuditDDL]
([EventData]
,[EventUser])
VALUES
('<EVENT_INSTANCE><EventType>BEGIN PATCH 17</EventType></EVENT_INSTANCE>'
,ORIGINAL_LOGIN())
GO
인덱스가 재 구축 될 때도 포착되므로 해당 이벤트를 지우려면 매월 다음을 실행해야합니다.
DELETE FROM AuditDDL
WHERE [EventData].exist('/EVENT_INSTANCE/EventType/text()[fn:contains(.,"ALTER_INDEX")]') =1
GO
DELETE FROM AuditDDL
WHERE [EventData].exist('/EVENT_INSTANCE/EventType/text()[fn:contains(.,"UPDATE_STATISTICS")]') =1
GO
이전 버전은 서버 결함에 게시되었습니다 .
SOX 및 PCI-DSS 호환 환경에서는 프로덕션 서버에 액세스 할 수 없습니다. 따라서 스크립트는 미리 명확하고 연습해야합니다. 업데이트 스크립트 맨 위에있는 주석에는 새 테이블, 저장된 proc, 함수 등의 목록과 수정 된 테이블, 저장된 proc, 함수 등이 포함됩니다. 데이터가 수정되면 수정중인 대상과 이유를 설명하십시오.
두 번째 문제점은 두 개의 개별 태스크가 동일한 데이터베이스 오브젝트를 변경하는 경우 변경 사항을 수동으로 조정해야하는 경우가 있습니다. 이것은 현재의 방식 일 수도 있지만 여전히 이러한 문제 나 무언가를 "비틀 거리는"자동화 된 방법이 있어야합니다.
나는 우리가 이것을 자동으로 추적 할 수있는 도구를 본 적이 없습니다. 이전 고용주는 "데이터베이스 소유자"라는 원칙을 사용했습니다. 데이터베이스를 개인적으로 담당하는 사람은 단 한 명입니다. 이 사람은 해당 데이터베이스에 대해 작업하는 유일한 개발자는 아니지만 모든 변경 작업을 수행해야합니다. 이것은 변경 사항이 서로 충돌하고 손상되지 않도록 합리적으로 잘 작동했습니다.