2011-10-07 7 views
1

내 애플리케이션에 자동 업데이트 기능을 제공해야합니다. SQL 업데이트 적용에 문제가 있습니다. 내 .sql 파일에 업데이트 된 SQL 문을 가지고 있고 달성하고자하는 것은 하나의 statment가 실패하면 전체 스크립트 파일을 롤백해야한다는 것입니다. Ex. 난의 제 문에서 오류 얻으면트랜잭션이 포함 된 스크립트 파일로 자동 업데이트

create procedure [dbo].[test1]   
@P1 varchar(200),   
@C1 int   
as   
begin 
Select 1 
end 

GO 

Insert into test (name) values ('vv') 

Go 

alter procedure [dbo].[test2]   
@P1 varchar(200),   
@C1 int   
as   
begin 
Select 1 
end 

GO 

이제 위의 예에서, "절차 [DBO] 변경할 수있다. [TEST2]"그럼 TEST1 "의 SP를 생성하는 또 처음 두 개의 변경을 롤백 할 "및"테스트 "테이블에 데이터 삽입

이 작업에 어떻게 접근해야합니까? 어떤 도움을 많이 주시면 감사하겠습니다.

당신이 어떤 더 많은 정보가 필요하면 다음, 시작 부분에 BEGIN TRAN을 추가 GO 문을 제거 한 다음 TRY..CATCH 블록과 ROLLBACK TRAN/COMMIT TRAN을 처리하는 것, 내가

답변

1

일반적으로 알 수 있습니다.

DML을 처리 할 때 일괄 처리의 시작 부분에 있어야하는 문이 종종 있기 때문에 TRY..CATCH 블록으로 래핑 할 수 없습니다. 이 경우 스스로 롤백하는 방법을 알고있는 시스템을 구성해야합니다.

단순한 시스템은 시작시 데이터베이스를 백업하고 실패 할 경우 복원하는 것입니다 (전체 시간 동안 데이터베이스에 액세스하는 유일한 사용자라고 가정). 또 다른 방법은 성공적으로 실행되는 각 일괄 처리를 기록하고 이후의 일괄 처리가 실패 할 경우 모든 것을 되돌리기 위해 실행할 수있는 해당 롤백 스크립트를 갖는 것입니다. 이것은 분명히 훨씬 많은 작업 (롤백을 완전히 테스트하는 모든 스크립트 PLUS에 대해 실행 취소 스크립트 작성)이 필요하며 업그레이드가 진행되는 동안 사람들이 데이터베이스에 계속 액세스하는 경우에도 문제가 될 수 있습니다.

편집 : 여기에 트랜잭션 처리와 간단한 TRY..CATCH 블록의 예 는 :

BEGIN TRY 

BEGIN TRANSACTION 

-- All of your code here, with `RAISERROR` used for any of your own error conditions 

COMMIT TRANSACTION 

END TRY 
BEGIN CATCH 
    ROLLBACK TRANSACTION 
END CATCH 

그러나 (배치를 확장 할 수 TRY..CATCH 블록은 어쩌면 내가 '트랜잭션이 나오지 않았어 말했을 때 나는 생각했다 무엇 t), 귀하의 경우에는 아마도 더 비슷한 것일 것입니다 :

IF (OBJECT_ID('dbo.Error_Happened') IS NOT NULL) 
    DROP TABLE dbo.Error_Happened 
GO 

BEGIN TRANSACTION 

<Some line of code> 

IF (@@ERROR <> 0) 
    CREATE TABLE dbo.Error_Happened (my_id INT) 

IF (OBJECT_ID('dbo.Error_Happened') IS NOT NULL) 
BEGIN 
    <Another line of code> 

    IF (@@ERROR <> 0) 
     CREATE TABLE dbo.Error_Happened (my_id INT) 
END 

... 

IF (OBJECT_ID('dbo.Error_Happened) IS NOT NULL) 
BEGIN 
    ROLLBACK TRANSACTION 
    DROP TABLE dbo.Error_Happened 
END 
ELSE 
    COMMIT TRANSACTION 

불행히도, t에서 별도의 배치 때문에 그는 GO 진술 GOTO을 사용할 수없고 TRY..CATCH을 사용할 수 없으며 배치 전체에 변수를 유지할 수 없습니다. 이것이 내가 오류를 나타 내기 위해 테이블을 만드는 아주 엉성한 트릭을 사용한 이유입니다.

더 좋은 방법은 단순히 오류 테이블을 가지고 그 행을 찾는 것입니다. ROLLBACK은 끝에있는 행을 삭제합니다.

+0

트랜잭션이 일괄 처리 할 수 ​​있습니다. –

+0

허. 왜 그들이 그렇게 할 수 없다고 생각하는지 모르겠다. 그 점을 지적 해 주셔서 감사합니다. 나는 그 대답을 삭제했다. 나는 나머지가 아직도 관련이 있다고 생각한다. –

+0

제안 해 주셔서 감사합니다. 데이터베이스가 너무 거대하여 백업/복원을 선호하지 않습니다. 두 번째 방법은 각 실행 된 SQL의 롤백 명령문을 만드는 것이 나을수록 좋습니다. 위 예제를 사용하여 어떻게 달성 할 수 있는지 말해 줄 수 있습니까? 많은 감사. – user867198

관련 문제