"배치"란 무엇이며 GO가 사용되는 이유는 무엇입니까?


134

MSDN 등을 읽고 읽었습니다. Ok, 배치의 끝을 알립니다.

배치를 정의하는 것은 무엇입니까? 여러 스크립트를 모두 동시에 실행하기 위해 붙여 넣을 때 왜 가야하는지 알 수 없습니다.

나는 GO를 이해하지 못했습니다. 누구든지 이것을 더 잘 설명하고 사용해야 할 때 (얼마나 많은 유형의 거래 후)?

예를 들어 각 업데이트 후에 왜 GO가 필요한가요?

 UPDATE [Country]
   SET [CountryCode] = 'IL'
 WHERE code = 'IL'

 GO

 UPDATE [Country]
   SET [CountryCode] = 'PT'
 WHERE code = 'PT'


FWIW, 변수 선언을 go재설정 / 삭제 하는 것처럼 보입니다 declare @foo- 주석을 때까지 @foo 오류 를 선언해야 했습니다 go.
JL Peyret

답변:


107

GO제대로 TSQL 명령 이 아닙니다 .

대신 SQL 서버에 연결 하는 특정 클라이언트 프로그램에 대한 명령입니다 (Sybase 또는 Microsoft-Oracle의 기능에 대해 잘 모름). "go"까지 필요할 때까지 입력 된 명령 세트를 클라이언트 프로그램에 알립니다. 실행할 서버로 전송됩니다.

왜 / 언제 필요합니까?

  • MS SQL 서버의 GO에는 "count"매개 변수가 있으므로 "repeat N times"단축키로 사용할 수 있습니다.

  • 매우 큰 업데이트는 SQL 서버의 로그를 채울 수 있습니다. 이를 피하기 위해을 통해 더 작은 배치로 분리해야 할 수도 있습니다 go.

    예를 들어, 국가 코드 세트에 대한 업데이트에 로그 공간이 부족한 볼륨이있는 경우 해결책은 각 국가 코드를 별도의 트랜잭션으로 분리하는 것입니다 go.이 코드 는 클라이언트에서로 분리하여 수행 할 수 있습니다 .

  • 일부 SQL 문은 다음 명령문과 GO로 구분해야 작동합니다.

    예를 들어, 적어도 Sybase (프로 시저 / 트리거 작성을위한 ditto)에서 단일 트랜잭션에서 테이블을 삭제하고 동일한 이름의 테이블을 다시 작성할 수 없습니다.

> drop table tempdb.guest.x1          
> create table tempdb.guest.x1 (a int)
> go
  Msg 2714, Level 16, State 1
  Server 'SYBDEV', Line 2
  There is already an object named 'x1' in the database.   
  
> drop table tempdb.guest.x1          
> go
> create table tempdb.guest.x1 (a int)
> go
>

4
GO 문은 트랜잭션을 생성하지 않습니다. 하나의 BEGIN TRANSACTION 문에 여러 GO 문을 포함시키고 결국 ROLLBACK을 수행하면 모든 GO 문이 롤백됩니다. 그리고 중간에 하나의 GO가 있으면 오류가 발생하고 결국 COMMIT을 수행하면 오류없이 모든 GO가 커밋됩니다. 까다 롭습니다.
TZ

7
GO"당신을위한 거래를 창출하지 않습니다". 명시 적 트랜잭션에서 실행되지 않으면 각 명령문은 자체 트랜잭션을 작성합니다. 완전히 직교합니다. 더 큰 업데이트를 더 작은 단계로 나누려면 공통 WHILE @@ROWCOUNT > 0패턴 과 같이 단일 배치로 업데이트를 수행 할 수 있습니다 .
Martin Smith

3
명시 적 트랜잭션으로 실행하지 않으면 어쨌든UPDATE T1 SET X =2;UPDATE T1 SET X =2; 두 개의 개별 트랜잭션으로 실행됩니다 . 추가 해도 아무런 차이가 없습니다. 그리고 당신은 비슷하게하면 된다 다시 배치를 걸쳐 명시 적 트랜잭션에서 실행하는 것은 차이가 없습니다. GOGO
Martin Smith

4
나중에 이것을 읽는 사람을 명확히하는 것과 마찬가지로 GO트랜잭션과 전혀 관련이 없으며 트랜잭션과 로그 파일의 크기에 대한 두 번째 대답이 잘못됩니다. GO아무 효과가 없습니다. 첫 번째와 세 번째 답변이 정확합니다. 또한 명령문을 별도의 배치로 분리해야하는 경우가 있습니다. 예를 들어 테이블에 컬럼을 추가 한 다음 나중에 동일한 배치에서 해당 컬럼을 사용할 수 없습니다. (계속)
Robert McKee

4
또한 일부 오류는 일괄 처리를 중단하기 때문에 (일부 오류는 명령문 만 중단하기 때문에) 오류 감지 및 복구에도 중요한 역할을합니다. 그리고 특정 진술 ( CREATE VIEW등)은 자체 배치에 있어야합니다.
Robert McKee

26

GO 명령문이 아니라 배치 구분 기호입니다.

구분 된 블록 GO은 처리를 위해 클라이언트에서 서버로 전송되며 클라이언트는 결과를 기다립니다.

예를 들어

DELETE FROM a
DELETE FROM b
DELETE FROM c

, 이것은 단일 행 3쿼리 로 서버에 전송됩니다 .

당신이 쓰는 경우

DELETE FROM a
GO
DELETE FROM b
GO
DELETE FROM c

이는 3한 줄 쿼리 로 서버에 전송됩니다 .

GO자체는 서버로 이동하지 않습니다. 순수한 클라이언트 측 예약어이며 다음에 의해서만 인식됩니다.SSMS 하고 osql.

사용자 정의 조회 도구를 사용하여 연결을 통해 보내면 서버는이를 인식하지 못하고 오류를 발행합니다.


4
왜 배치를해야합니까 ??
PositiveGuy

3
따라서 GO는 보낸 다음 클라이언트가 "OK, 해당 일괄 처리가 완료되고 성공했습니다"라는 메시지가 나타날 때까지 다음 일괄 처리를 실행하지 않음을 의미합니다. 기본적으로 다음 일괄 처리가 성공적으로 실행되고 클라이언트가 배치가 서버 측에서 완료되기 전에 확인하십시오.
PositiveGuy

3
@coffeeaddict : 기본적으로 그렇습니다. 또한 일부 문장은 배치에서 첫 번째 여야합니다 (예 :) CREATE SCHEMA. 다른 하나는 인 요구 (같은 자신의 일괄 문 SET SHOWPLAN_XML ON)
Quassnoi

19

많은 명령은 자체 배치에 있어야합니다. CREATE PROCEDURE

또는 테이블에 열을 추가하면 자체 배치에 있어야합니다. 동일한 배치에서 새 열을 SELECT하려고하면 구문 분석 / 컴파일시 열이 없으므로 실패합니다.

GO는 SQL 도구에서 하나의 스크립트에서이를 해결하는 데 사용됩니다. SQL 키워드가 아니며 엔진에서 인식하지 못합니다.

다음은 배치를 매일 사용하는 구체적인 예입니다.

편집 : 귀하의 예에서는 GO가 필요하지 않습니다 ...

예 2를 편집하십시오. 하나의 배치에서 삭제, 작성 및 권한 부여를 할 수 없습니다. 적어도 저장 프로 시저의 끝은 어디에 있습니까?

IF OBJECT_ID ('dbo.uspDoStuff') IS NOT NULL
    DROP PROCEDURE dbo.uspDoStuff
GO
CREATE PROCEDURE dbo.uspDoStuff
AS
SELECT Something From ATable
GO
GRANT EXECUTE ON dbo.uspDoStuff TO RoleSomeOne
GO

4

때때로 동일한 명령 또는 일련의 명령을 반복해서 실행해야 할 필요가 있습니다. 테스트 데이터를 삽입하거나 업데이트하거나 성능 테스트를 위해 서버에 부하를 줄 수 있습니다. 가장 쉬운 방법은 while 루프를 설정하고 코드를 실행하는 것이지만 SQL 2005에서는이를 수행하는 훨씬 쉬운 방법이 있습니다.

테스트 테이블을 작성하고 1000 개의 레코드로로드하려고한다고 가정하십시오. 다음 명령을 실행할 수 있으며 동일한 명령을 1000 회 실행합니다.

CREATE TABLE dbo.TEST (ID INT IDENTITY (1,1), ROWID uniqueidentifier)
GO
INSERT INTO dbo.TEST (ROWID) VALUES (NEWID()) 
GO 1000

출처 : http://www.mssqltips.com/tip.asp?tip=1216

그 외에는 SQL 블록의 "종료"를 표시합니다 (예 : 저장 프로 시저에서). 더 이상 정의되지 않음)


좋아, 왜 GO가 필요한가요? 삽입 명령문이 실행되기 전에 테이블이 작성되었음을 알고 있습니까? 나는 아직도 그것을 얻지 못한다.
PositiveGuy

내가 생각하는 방식을 참조하십시오. 귀하의 예제에 GO가 없으면 Table이 먼저 생성되어 테이블이 있으므로 삽입이 작동한다는 것입니다. 테이블을 만들면 GO가 무엇인지 알 수 없습니다 ... 다음 삽입에 사용할 수 있습니까?!?!?!
PositiveGuy

2
@coffeeaddict : 아니오. "일괄 처리"는 한 번에 구문 분석되고 컴파일됩니다. 컴파일시 dbo.TEST가 존재하지 않습니다. 객체를 인스턴스화하지 않고 SQL이 라인 단위 절차 코드가 아님
gbn

3

모든 사람들이 이미 말했듯이 "GO"는 T-SQL의 일부가 아닙니다. "GO"는 SSMS 의 배치 구분 기호 입니다. 데이터베이스에 쿼리를 제출하는 데 사용되는 클라이언트 응용 프로그램 인 . 이는 선언 된 변수 및 테이블 변수가 "GO"앞의 코드에서 그 뒤에 오는 코드로 유지되지 않음을 의미합니다.

실제로 GO는 SSMS에서 사용 하는 기본 단어입니다. 원하는 경우 옵션에서 변경할 수 있습니다. 약간의 재미를 위해 다른 사람의 시스템에서 "GO"대신 "SELECT"를 배치 구분자로 사용하도록 옵션을 변경하십시오. 잔인한 멍청이를 용서하십시오.


1
실제로 여기서 고려해야 할 중요한 점이 있습니다. GO는 키워드가 아닌 키워드 인 것처럼 취급해야합니다. 또한 절대로 변경해서는 안됩니다. 특수 식별자를 재사용하여 발생하는 버그는 디버깅하기가 매우 어려울 수 있습니다.
Jørgen Fogh 2016 년

@ 딕시 플랫 라인 : 선언 된 변수가 지속되지 않습니까? MSSQL 2016에서 다음을 실행할 때 "변수가 이미 선언되었습니다"라는 오류가 발생합니다. 선언 $ test int; $ test = 5로 설정; $ test go를 선택하십시오; $ test int 선언; -$를 <at>로 바꾸고 SE 주석에서 여러 <at>을 사용할 수 없습니다.
Wouter

0

논리 블록을 분할하는 데 사용됩니다. 코드는 sql 명령 줄로 해석되며 다음 코드 블록을 나타냅니다.

그러나 특정 번호의 재귀 진술로 사용할 수 있습니다.

시험:

exec sp_who2  
go 2

GO로 일부 문장을 구분해야합니다.

use DB
create view thisViewCreationWillFail
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.