[sql-server] SQL Server에서 Begin / End Blocks 및 Go 키워드는 언제 사용해야합니까?
누군가 SQL Server에서 언제 어디서 사용 begin
하고 end
차단 해야하는지 알려줄 수 있습니까 ?
또한 Go
키워드는 정확히 무엇을 합니까?
답변
GO는 스크립트의 끝과 같습니다.
GO로 구분 된 여러 CREATE TABLE 문이있을 수 있습니다. 스크립트의 한 부분을 다른 부분과 분리하는 방법이지만 모두 한 블록에 제출합니다.
BEGIN과 END는 C / ++ / #, Java 등에서 {및}와 같습니다.
그들은 논리적 코드 블록을 묶었습니다. 저장 프로 시저의 시작과 끝 부분에 BEGIN과 END를 사용하는 경향이 있지만 꼭 필요한 것은 아닙니다. 필요한 곳은 for 루프, IF 문 등이며 한 단계 이상이 필요합니다.
IF EXISTS (SELECT * FROM my_table WHERE id = @id)
BEGIN
INSERT INTO Log SELECT @id, 'deleted'
DELETE my_table WHERE id = @id
END
답변
둘 이상의 문에 걸쳐있는 블록을 만들려면 BEGIN … END가 필요합니다. 따라서 IF 문의 하나의 ‘leg’에서 두 가지 작업을 수행하거나 WHILE 루프 본문에서 두 가지 이상의 작업을 수행하려면 해당 구문을 BEGIN … 종료.
GO 키워드는 SQL의 일부가 아닙니다. 쿼리 분석기에서 스크립트를 독립적으로 실행되는 “일괄 처리”로 나누는 데만 사용됩니다.
답변
GO는 SQL Server의 키워드가 아닙니다. 배치 구분자입니다. GO는 문 배치를 끝냅니다. 이것은 SQLCMD와 같은 것을 사용할 때 특히 유용합니다. 명령 줄에 SQL 문을 입력한다고 상상해보십시오. 명령문을 끝낼 때마다 해당 작업이 실행되는 것을 원하지는 않으므로 SQL Server는 “GO”를 입력 할 때까지 아무 작업도 수행하지 않습니다.
마찬가지로 배치가 시작되기 전에 종종 일부 개체를 표시해야합니다. 예를 들어 데이터베이스를 만든 다음 쿼리한다고 가정 해 보겠습니다. 다음과 같이 쓸 수 없습니다.
CREATE DATABASE foo;
USE foo;
CREATE TABLE bar;
foo는 CREATE TABLE을 수행하는 배치에 대해 존재하지 않기 때문입니다. 다음을 수행해야합니다.
CREATE DATABASE foo;
GO
USE foo;
CREATE TABLE bar;
답변
BEGIN과 END는 다른 사람들로부터 좋은 답변을 받았습니다.
Gary가 지적했듯이 GO는 isql, sqlcmd, 쿼리 분석기 및 SQL Server Management Studio와 같은 대부분의 Microsoft 제공 클라이언트 도구에서 사용되는 배치 구분 기호입니다. (적어도 일부 도구를 사용하면 배치 구분 기호를 변경할 수 있습니다. 배치 구분 기호를 변경하는 용도는 본 적이 없습니다.)
GO를 언제 사용해야하는지에 대한 질문에 답하려면 SQL을 배치로 분리해야하는시기를 알아야합니다.
일부 문은 배치의 첫 번째 문이어야합니다.
select 1
create procedure #Zero as
return 0
SQL Server 2000에서 오류는 다음과 같습니다.
Msg 111, Level 15, State 1, Line 3
'CREATE PROCEDURE' must be the first statement in a query batch.
Msg 178, Level 15, State 1, Line 4
A RETURN statement with a return value cannot be used in this context.
SQL Server 2005에서는 오류가 덜 유용합니다.
Msg 178, Level 15, State 1, Procedure #Zero, Line 5
A RETURN statement with a return value cannot be used in this context.
따라서 GO
스크립트에서 배치의 시작이되어야하는 문과 그 앞에 오는 문을 구분하는 데 사용하십시오.
스크립트를 실행할 때 많은 오류로 인해 일괄 처리 실행이 중지되지만 클라이언트는 단순히 다음 일괄 처리를 전송하고 스크립트 실행은 중지되지 않습니다. 나는 종종 이것을 테스트에 사용합니다. 트랜잭션 시작으로 스크립트를 시작하고 롤백으로 끝내고 중간에 모든 테스트를 수행합니다.
begin transaction
go
... test code here ...
go
rollback transaction
이렇게하면 테스트 코드에서 오류가 발생하더라도 항상 시작 상태로 돌아갑니다. 별도의 일괄 처리의 일부인 시작 및 롤백 트랜잭션 문은 계속 발생합니다. 별도의 배치에 있지 않은 경우 배치가 단위로 구문 분석되므로 구문 오류로 인해 트랜잭션 시작이 발생하지 않습니다. 그리고 런타임 오류로 인해 롤백이 발생하지 않습니다.
또한 설치 스크립트를 수행하고 있고 하나의 파일에 여러 배치가있는 경우 한 배치의 오류로 인해 스크립트가 계속 실행되지 않아 엉망이 될 수 있습니다. (설치하기 전에 항상 백업하십시오.)
Dave Markel이 지적한 것과 관련하여 SQL Server가 데이터 사전에서 일괄 처리 초기에 생성 된 개체를 찾고 있기 때문에 구문 분석이 실패하는 경우가 있지만 구문이 실행되기 전에 구문 분석이 발생할 수 있습니다. 때때로 이것은 문제가되고 때로는 그렇지 않습니다. 좋은 예를 찾을 수 없습니다. 그러나 ‘X가 존재하지 않습니다’오류가 발생하면 해당 문에 의해 분명히 존재할 때 일괄 처리로 나뉩니다.
그리고 마지막 메모. 트랜잭션은 배치에 걸쳐있을 수 있습니다. (위 참조) 변수는 배치에 걸쳐 있지 않습니다.
declare @i int
set @i = 0
go
print @i
Msg 137, Level 15, State 2, Line 1
Must declare the scalar variable "@i".
답변
GO는 일괄 처리를 종료하므로 코드에서 거의 사용할 필요가 없습니다. 저장된 proc에서 사용하는 경우 proc을 실행할 때 GO 이후의 코드가 실행되지 않습니다.
BEGIN 및 END는 처리 할 여러 줄의 코드가있는 모든 절차 유형 문에 필요합니다. WHILE 루프와 커서 (물론 가능하면 피할 것임) 및 IF 문 (기술적으로 코드가 한 줄만있는 IF 문에는 필요하지 않지만 더 쉽습니다. IF 뒤에 항상 넣으면 코드를 유지하십시오). CASE 문도 END를 사용하지만 BEGIN은 없습니다.
답변
이 문제와 씨름 한 후 오늘 내 의견은 다음과 같습니다. BEGIN … END C 언어에서하는 것처럼 BEGIN … END 대괄호 코드, 예를 들어 if … else 및 루프에 대한 코드 블록
GO는 다음 문이 이전 문에서 정의한 개체에 의존 할 때 사용됩니다 (반드시 사용). USE 데이터베이스는 위의 좋은 예이지만 다음도 당신을 물릴 것입니다.
alter table foo add bar varchar(8);
-- if you don't put GO here then the following line will error as it doesn't know what bar is.
update foo set bar = 'bacon';
-- need a GO here to tell the interpreter to execute this statement, otherwise the Parser will lump it together with all successive statements.
나에게 문제는 이것 인 것 같습니다. Oracle과 달리 SQL Server SQL Parser는 첫 번째 줄에 새 기호를 정의하고 다음 줄에서 참조해도 괜찮다는 것을 인식 할 수 없습니다. 마지막 GO 이후 선행 SQL을 실행하도록 지시하는 GO 토큰을 만날 때까지 기호를 “보지”않습니다.이 시점에서 기호는 데이터베이스에 적용되고 파서에 표시됩니다.
세미콜론을 의미 론적 구분으로 취급하지 않고 개별적으로 문을 적용하지 않는 이유는 모르겠지만 그렇게 되었으면합니다. 내가 볼 수있는 유일한 보너스는 GO 바로 앞에 print () 문을 넣을 수 있으며 문 중 하나라도 실패하면 인쇄가 실행되지 않는다는 것입니다. 그러나 사소한 이득을 위해 많은 문제가 있습니다.