복붙노트

[SQL] TSQL가 - A는 ... END 블록을 BEGIN의 방법 GO의 내부를 사용 하는가?

SQL

TSQL가 - A는 ... END 블록을 BEGIN의 방법 GO의 내부를 사용 하는가?

나는 준비 / 생산 여러 개발 데이터베이스에서 자동으로 마이그레이션 변경하는 스크립트를 생성하고있다. 기본적으로, BEGIN 어떤 ... END 문을 IF에서 각 스크립트를 포장, 하나의 스크립트로 변화 스크립트 및 병합을 잔뜩합니다.

그것이 만들어지는 후에 즉, 예를 들어, SQL 파서는 새로운 칼럼에 대해 알 수 있도록하지만, 스크립트의 일부는 GO 문을 필요로한다.

ALTER TABLE dbo.EMPLOYEE 
ADD COLUMN EMP_IS_ADMIN BIT NOT NULL
GO -- Necessary, or next line will generate "Unknown column:  EMP_IS_ADMIN"
UPDATE dbo.EMPLOYEE SET EMP_IS_ADMIN = whatever

그러나, 나는이 IF 블록에서 그 포장 후 :

IF whatever
BEGIN
    ALTER TABLE dbo.EMPLOYEE ADD COLUMN EMP_IS_ADMIN BIT NOT NULL
    GO
    UPDATE dbo.EMPLOYEE SET EMP_IS_ADMIN = whatever
END

나는이 일치 END로 시작 보내고 있기 때문에 실패합니다. 나는 GO를 제거하는 경우 그러나, 그것은 알 수없는 컬럼에 대해 다시 뿌려줍니다.

하나의 IF 블록 내에서 동일한 열을 생성하고 업데이트 할 수있는 방법이 있습니까?

해결법

  1. ==============================

    1.GO는 SQL되지 않습니다 - 단순히 일부 MS SQL 도구에 사용되는 배치 구분이다.

    GO는 SQL되지 않습니다 - 단순히 일부 MS SQL 도구에 사용되는 배치 구분이다.

    당신이를 사용하지 않는 경우, 별도로 실행되는 명령문을 확인해야합니다 - 다른 일괄 또는 인구 (감사 @gbn)에 대한 동적 SQL을 사용하여 다음 중 하나를

    IF whatever
    BEGIN
        ALTER TABLE dbo.EMPLOYEE ADD COLUMN EMP_IS_ADMIN BIT NOT NULL;
    
        EXEC ('UPDATE dbo.EMPLOYEE SET EMP_IS_ADMIN = whatever')
    END
    
  2. ==============================

    2.저도 같은 문제를 겪고 마침내 SET NOEXEC를 사용하여 해결할 수 있었다.

    저도 같은 문제를 겪고 마침내 SET NOEXEC를 사용하여 해결할 수 있었다.

    IF not whatever
    BEGIN
        SET NOEXEC ON; 
    END
    
    ALTER TABLE dbo.EMPLOYEE ADD COLUMN EMP_IS_ADMIN BIT NOT NULL
    GO
    UPDATE dbo.EMPLOYEE SET EMP_IS_ADMIN = whatever
    
    SET NOEXEC OFF; 
    
  3. ==============================

    3.당신은 아래의 예제와 같이 별도의 문자열로 각 GO 문 사이의 내용이 실행되는 분할, sp_executesql을을 시도 할 수 있습니다. 또한, 예외가 발생한 위치를 쉽게 디버깅 실행되고있는 문 추적하는 @statementNo 변수가있다. 라인 번호는 오류를 발생 관련 문 번호의 시작 부분에 상대적 될 것입니다.

    당신은 아래의 예제와 같이 별도의 문자열로 각 GO 문 사이의 내용이 실행되는 분할, sp_executesql을을 시도 할 수 있습니다. 또한, 예외가 발생한 위치를 쉽게 디버깅 실행되고있는 문 추적하는 @statementNo 변수가있다. 라인 번호는 오류를 발생 관련 문 번호의 시작 부분에 상대적 될 것입니다.

    BEGIN TRAN
    
    DECLARE @statementNo INT
    BEGIN TRY
        IF 1=1
        BEGIN
            SET @statementNo = 1
            EXEC sp_executesql
                N'  ALTER TABLE dbo.EMPLOYEE
                        ADD COLUMN EMP_IS_ADMIN BIT NOT NULL'
    
            SET @statementNo = 2
            EXEC sp_executesql
                N'  UPDATE dbo.EMPLOYEE
                        SET EMP_IS_ADMIN = 1'
    
            SET @statementNo = 3
            EXEC sp_executesql
                N'  UPDATE dbo.EMPLOYEE
                        SET EMP_IS_ADMIN = 1x'
        END
    END TRY
    BEGIN CATCH
        PRINT 'Error occurred on line ' + cast(ERROR_LINE() as varchar(10)) 
           + ' of ' + 'statement # ' + cast(@statementNo as varchar(10)) 
           + ': ' + ERROR_MESSAGE()
        -- error occurred, so rollback the transaction
        ROLLBACK
    END CATCH
    -- if we were successful, we should still have a transaction, so commit it
    IF @@TRANCOUNT > 0
        COMMIT
    

    당신은 쉽게 간단하게 작은 따옴표 ( ')에 그들을 배치하여 같은 위의 예에서 보여준 여러 줄 문을 실행할 수 있습니다. 스크립트를 생성 할 때 이중 따옴표 ( '')로 문자열 안에 포함 된 작은 따옴표를 탈출하는 것을 잊지 마십시오.

  4. ==============================

    4.나는 궁극적으로 자신의 줄에 GO의 모든 인스턴스를 대체하여 작업에있어

    나는 궁극적으로 자신의 줄에 GO의 모든 인스턴스를 대체하여 작업에있어

    END
    GO
    
    ---Automatic replacement of GO keyword, need to recheck IF conditional:
    IF whatever
    BEGIN
    

    이 문자열에 문의 모든 그룹을 포장에 매우 바람직하지만 지금까지 이상에서 아직도있다. 사람이 더 나은 솔루션을 발견하면, 그것을 게시하고 내가 대신 그것을 받아 들일 것이다.

  5. ==============================

    5.당신은 BEGIN에서 문 및 END 대신 사이에서 GO를 동봉 수

    당신은 BEGIN에서 문 및 END 대신 사이에서 GO를 동봉 수

    IF COL_LENGTH('Employees','EMP_IS_ADMIN') IS NULL --Column does not exist
    BEGIN
        BEGIN
            ALTER TABLE dbo.Employees ADD EMP_IS_ADMIN BIT
        END
    
        BEGIN
            UPDATE EMPLOYEES SET EMP_IS_ADMIN = 0
        END
    END
    

    (Northwind 데이터베이스에서 테스트)

    편집 : (아마 2012 SQL 테스트)

  6. ==============================

    6.이 솔루션을 시도 할 수 있습니다 :

    이 솔루션을 시도 할 수 있습니다 :

    if exists(
    SELECT...
    )
    BEGIN
    PRINT 'NOT RUN'
    RETURN
    END
    
    --if upper code not true
    
    ALTER...
    GO
    UPDATE...
    GO
    
  7. ==============================

    7.나는이에 대한 과거 RAISERROR를 사용했다

    나는이에 대한 과거 RAISERROR를 사용했다

    IF NOT whatever BEGIN
        RAISERROR('YOU''RE ALL SET, and sorry for the error!', 20, -1) WITH LOG
    END
    
    ALTER TABLE dbo.EMPLOYEE ADD COLUMN EMP_IS_ADMIN BIT NOT NULL
    GO
    UPDATE dbo.EMPLOYEE SET EMP_IS_ADMIN = whatever
    
  8. ==============================

    8.당신은 따라서 키워드 그대로 GO를 떠나, 코드를 건너 뛸 수있는 GOTO 및 LABEL 문을 통합 할 수 있습니다.

    당신은 따라서 키워드 그대로 GO를 떠나, 코드를 건너 뛸 수있는 GOTO 및 LABEL 문을 통합 할 수 있습니다.

  9. from https://stackoverflow.com/questions/6376866/tsql-how-to-use-go-inside-of-a-begin-end-block by cc-by-sa and MIT license