TSQL-BEGIN .. END 블록 내에서 GO를 사용하는 방법?
여러 개발 데이터베이스의 변경 사항을 스테이징 / 프로덕션으로 자동 마이그레이션하는 스크립트를 생성하고 있습니다. 기본적으로 많은 변경 스크립트를 사용하여 단일 스크립트로 병합하여 각 스크립트를 IF whatever BEGIN ... END
명령문으로 래핑 합니다.
그러나 일부 스크립트에는 GO
예를 들어 SQL 파서가 새 열이 생성 된 후 새 열에 대해 알 수 있도록 문이 필요합니다 .
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
BEGIN
일치하지 않는를 보내고 있기 때문에 실패합니다 END
. 그러나 내가 제거 GO
하면 알 수없는 열에 대해 다시 불평합니다.
단일 IF
블록 내에서 동일한 열을 만들고 업데이트하는 방법이 있습니까?
GO
SQL이 아닙니다. 일부 MS SQL 도구에서 사용되는 배치 구분 기호 일뿐입니다.
이를 사용하지 않는 경우 다른 배치로 또는 모집단에 대한 동적 SQL을 사용하여 문이 별도로 실행되는지 확인해야합니다 (@gbn에게 감사드립니다).
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
나는 같은 문제가 있었고 마침내 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;
당신은 시도해 볼 수도 있습니다 sp_executesql
각각의 내용을 분할, GO
아래 예제와 같이 별도의 문자열로 문을 실행 할 수 있습니다. 또한 예외가 발생한 위치를 쉽게 디버깅 할 수 있도록 실행중인 문을 추적하는 @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
You can also easily execute multi-line statements, as demonstrated in the example above, by simply wrapping them in single quotes ('
). Don't forget to escape any single quotes contained inside the string with a double single-quote (''
) when generating the scripts.
I ultimately got it to work by replacing every instance of GO
on its own line with
END
GO
---Automatic replacement of GO keyword, need to recheck IF conditional:
IF whatever
BEGIN
This is greatly preferable to wrapping every group of statements in a string, but is still far from ideal. If anyone finds a better solution, post it and I'll accept it instead.
You can enclose the statements in BEGIN and END instead of the GO inbetween
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
(Tested on Northwind database)
Edit: (Probably tested on SQL2012)
I have used RAISERROR
in the past for this
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
You may try this solution:
if exists(
SELECT...
)
BEGIN
PRINT 'NOT RUN'
RETURN
END
--if upper code not true
ALTER...
GO
UPDATE...
GO
You can incorporate a GOTO
and LABEL
statements to skip over code, thus leaving the GO
keywords intact.
참고URL : https://stackoverflow.com/questions/6376866/tsql-how-to-use-go-inside-of-a-begin-end-block
'program story' 카테고리의 다른 글
HTML5 (0) | 2020.09.08 |
---|---|
INNER JOIN 조건에 'OR'이있는 것이 나쁜 생각입니까? (0) | 2020.09.08 |
Django 가져 오기 오류-django.conf.urls.defaults라는 모듈이 없습니다. (0) | 2020.09.07 |
numpy 배열을 내림차순으로 효율적으로 정렬 하시겠습니까? (0) | 2020.09.07 |
SVG 모양의 특정면에만 획 너비 : 1을 설정하는 방법은 무엇입니까? (0) | 2020.09.07 |