2009-07-24 2 views

답변

84

GO는 스크립트의 끝과 같습니다.

GO로 구분 된 여러 CREATE TABLE 문을 사용할 수 있습니다. 스크립트의 한 부분을 다른 부분과 분리하여 하나의 블록으로 모두 제출하는 방법입니다.


는 BEGIN 및 END는

그들은 코드의 논리 블록을 결합 등 C/++/#, 자바,에서와 같이 {와}입니다. BEGIN과 END는 저장 프로 시저의 시작과 끝에서 사용하는 경향이 있지만 엄격하게 필요하지는 않습니다. 이 필요한 경우 루프이며, 문, 등, 당신이 더 한 단계 다음 필요로하는 곳에 ... 경우

IF EXISTS (SELECT * FROM my_table WHERE id = @id) 
BEGIN 
    INSERT INTO Log SELECT @id, 'deleted' 
    DELETE my_table WHERE id = @id 
END 
+0

BEGIN 및 END없이 SP를 만들려고 했습니까? IIRC에서는 첫 번째 줄만 SP에 포함되며 나머지는 방금 실행 된 다음 ... – cjk

+1

SQL Server 2000 이후의 경험은 분명히 아닙니다. – MatBailie

29

둘 이상의 명령문에 걸친 블록을 작성하려면 BEGIN ... END가 필요합니다. 그래서 IF 문에서 하나의 '다리'에서 2 가지 작업을 수행하려는 경우 또는 WHILE 루프 본문에서 두 가지 이상을 수행하려는 경우 BEGIN을 사용하여 문을 브래킷 (bracket)으로 묶어야합니다. 종료.

GO 키워드는 SQL의 일부가 아닙니다. Query Analyzer는 스크립트를 독립적으로 실행되는 "배치"로 나눕니다.

+1

+1 빠른 입력 : – MatBailie

+0

+1 간결하고 정확한 – Frozenskys

19

GO는 SQL Server의 키워드 아니다; 배치 분리기입니다. GO는 일련의 진술을 종료합니다. 이것은 SQLCMD와 같은 것을 사용할 때 특히 유용합니다. 명령 줄에 SQL 문을 입력한다고 가정 해보십시오. 성명을 끝낼 때마다 반드시 실행해야하는 것은 아니므로 SQL Server는 "GO"를 입력 할 때까지 아무 것도하지 않습니다.

마찬가지로 배치가 시작되기 전에 일부 개체를 볼 필요가 있습니다. 예를 들어, 데이터베이스를 작성한 후 쿼리한다고 가정 해 보겠습니다. 다음과 같이 쓸 수 없습니다 :

CREATE TABLE을 수행하는 배치에 foo가 없기 때문에 작성할 수 없습니다. 다음을 수행해야합니다.

CREATE DATABASE foo; 
GO 
USE foo; 
CREATE TABLE bar; 
2

GO는 일괄 처리를 끝내지 만 코드에서 사용할 필요는 거의 없습니다. 스토어드 프로 시저에서 사용하면, 프로 시저를 실행할 때 GO 다음에 코드가 실행되지 않는다는 점에 유의하십시오.

BEGIN 및 END는 처리 할 멀티 코드 줄이있는 모든 프로 시저 유형 문에 필요합니다. WHILE 루프와 커서 (물론 가능하다면 피할 것입니다)와 IF 문 (물론 한 줄의 코드 만 가진 IF 문법을 필요로하지는 않지만 기술적으로 더 쉽게 작성할 수 있습니다. IF 이후에 항상 코드를 유지한다면 코드를 유지하십시오). CASE 문은 END를 사용하지만 BEGIN이 없습니다.

+0

GO 이후의 코드는 실제로 저장된 proc에 대해 저장됩니까? GO가 존재하지 않으면 코드가있는 것처럼 CREATE 또는 ALTER 문을 처리하지 않습니까? 그런 다음 GO가 실행 된 후의 코드가 마치 자신의 스크립트 인 것처럼 실행됩니다. – MatBailie

+0

커서는 어떤 점이 있습니까? –

+0

글쎄, 현실적으로 커서를 사용하려면 루프가 필요합니다 ... – MatBailie

8

BEGIN 및 END는 다른 사람들로부터 잘 답변되었습니다.

게리가 지적한대로 GO는 Microsoft에서 제공하는 대부분의 isql, sqlcmd, 쿼리 분석기 및 SQL Server Management Studio와 같은 클라이언트 도구에서 사용되는 배치 구분 기호입니다. (도구 중 적어도 일부는 배치 구분 기호를 변경할 수 있습니다. 배치 구분 기호를 변경하는 용도는 본 적이 없습니다.)

GO를 사용할 때의 질문에 답하려면 SQL을 일괄 처리로 구분해야 할시기를 알아야합니다.

일부 문은 일괄 처리의 첫 번째 문이어야합니다. SQL 서버에

select 1 
create procedure #Zero as 
    return 0 

2000 오류는 다음과 같습니다

Msg 178, Level 15, State 1, Procedure #Zero, Line 5 
A RETURN statement with a return value cannot be used in this context. 

그래서해야 문을 분리 GO를 사용 SQL 서버에

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. 

2005 오류가 적은 도움이됩니다 스크립트에서 앞에 오는 명령문에서 배치의 시작.

스크립트를 실행하면 많은 오류로 인해 배치 실행이 중지되지만 클라이언트가 다음 배치를 보내면 스크립트 실행이 중지되지 않습니다. 나는 종종 이것을 테스트에 사용한다. 나는 중간에있는 모든 테스트를하고, 트랜잭션을 시작하고 롤백 끝이 스크립트를 시작합니다 :

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". 
+1

이것은 내가 필요한 것이므로 감사합니다 : "트랜잭션은 배치를 확장 할 수 있습니다. 변수는 배치를 확장하지 않습니다." – Gary

1

오늘이 문제와 씨름 한 후 내 의견은 이것이다 : BEGIN ... 단지 같은 END 브래킷 코드를 {....} C 언어, 예를 들어,에서와 if ... else 및 루프에 대한 코드 블록

GO는 후행 명령문이 이전 명령문에서 정의 된 개체에 의존 할 때 사용됩니다 (반드시 사용해야 함). '당신 실현하기 위해 SQL 서버 SQL 파서, 오라클 하나는 달리,없는 : 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. 

문제는 이것이다 첫 줄에 새 기호를 정의하고 다음 줄에서 참조하는 것이 좋습니다. 마지막 GO 이후의 이전 SQL을 실행하도록 지시하는 GO 토큰을 만나기 전까지는 심볼을 "보지"않습니다. 이때 심볼은 데이터베이스에 적용되고 파서가 볼 수있게됩니다.

왜 단지 세미콜론을 의미있는 중단으로 간주하고 개별적으로 문장을 적용하지 않는 이유는 모르겠다.볼 수있는 보너스는 GO 직전에 print() 문을 넣을 수 있으며 명령문 중 하나라도 실패하면 인쇄가 실행되지 않는다는 것입니다. 작은 이득을위한 많은 문제.

관련 문제