SQL Server에서 세미콜론을 언제 사용해야합니까?


221

웹에서 일부 코드와 SQL Server Management Studio에서 생성 한 스크립트를 확인하는 동안 일부 문이 세미콜론으로 끝나는 것을 알았습니다.

언제 사용해야합니까?


23
SQL Server 2008 R2 msdn.microsoft.com/en-us/library/ms177563.aspx "Transact-SQL 구문 규칙 (Transact-SQL)" ; == Transact-SQL 문 종결 자 이 버전 의 SQL Server에서는 대부분의 명령문에 세미콜론이 필요하지 않지만 향후 버전 에서는 세미콜론이 필요합니다 .
gerryLowry

2
향후 버전에서는 세미콜론이 필요하다고 주장하지만 이것은 결코 이루어질 수 없습니다. 호환성 문제로 인해이를 요구할 수는 없습니다. 약 100 %의 응용 프로그램이 중단됩니다.
usr

1
현재 2019 년이며 최신 버전의 SQL Server에서 세미콜론을 여전히 행복하게 받아들이지 않습니다. @usr이 말했듯이, Microsoft가 100 % 깔끔한 휴식을 취하지 않는 한,이를 강제 할 수있는 방법은 없습니다.
이안 켐

답변:


152

Ken Powers 의 SQLServerCentral.Com 기사 에서 :

세미콜론

세미콜론 문자는 명령문 종결 자입니다. ANSI SQL-92 표준의 일부이지만 Transact-SQL에서는 사용되지 않았습니다. 실제로 세미콜론 없이도 수년 동안 T-SQL을 코딩 할 수있었습니다.

용법

세미콜론을 사용해야하는 두 가지 상황이 있습니다. 첫 번째 상황은 CTE (Common Table Expression)를 사용하는 곳이며 CTE는 배치의 첫 번째 문이 아닙니다. 두 번째는 Service Broker 문을 발행하는 지점이며 Service Broker 문은 배치의 첫 번째 문이 아닙니다.


9
THROW서비스 브로커 문은? : 우리는이 예에서 던져 이전에 세미콜론을 포함 할 필요가BEGIN ;THROW @Error, 'Invalid FundingID', 2; RETURN END
크리스 월시

1
최근에 도입 된 모든 새로운 문장 유형보다 먼저 세미콜론을 요구함으로써 기본적으로 세미콜론의 사용을 권장하고있는 것 같습니다. ( MERGE예를 들어). 다른 답변에서 언급했듯이 ANSI 표준에서는 필수입니다
Mark Sowul

2
@maurocam 문서를 잘못 읽은 것 같습니다. 해당 링크를 보면 " 세미콜론으로 Transact-SQL 문을 끝내지 않습니다 "라는 메시지 가 나타 납니다. 더 이상 사용되지 않습니다.
Caltor

내가 그것을보고, 이건 정말 사람이 할 때의 문제가 해결되지 않습니다 해야한다 (반대 필수 ) 세미콜론을 사용합니다.
스튜어트

81

기본적으로 SQL 문은 세미콜론으로 종료됩니다. 새 문 종결자를 설정하지 않은 경우 세미콜론을 사용하여 문을 종료합니다.

하나의 명세서 만 보내면 기술적으로 명세서 종결자를 생략 할 수 있습니다. 스크립트에서 둘 이상의 문장을 보낼 때 필요합니다.

실제로 데이터베이스에 하나의 명령문을 보내는 경우에도 항상 종결자를 포함하십시오.

편집 : [특정 RDBMS]에는 명령문 종결자가 필요하지 않다는 말에 응답하여 사실 일 수도 있지만 ANSI SQL 표준에 필요합니다. 모든 프로그래밍에서 기능 손실없이 표준을 준수 할 수 있다면 코드 나 습관이 하나의 독점 공급 업체와 연결되어 있지 않기 때문입니다.

일부 C 컴파일러의 경우 표준에 main이 int를 반환해야하더라도 main return void가 가능합니다. 그러나 그렇게하면 코드와 이식성이 떨어집니다.

효과적인 프로그래밍의 가장 큰 어려움은 새로운 것을 배우는 것이 아니라 나쁜 습관을 배우지 않는 것입니다. 처음에는 나쁜 습관을 습득 할 수 없을 정도로 우리, 우리의 코드, 코드를 읽거나 사용하는 사람에게는 승리입니다.



25

당신은 해야한다 그것을 사용할 수 있습니다.

명령문을 종료하기 위해 세미콜론을 사용하는 방법은 표준이며 실제로 다른 여러 데이터베이스 플랫폼에서는 필수입니다. SQL Server에는 특정 경우에만 세미콜론이 필요하지만 세미콜론이 필요하지 않은 경우 세미콜론을 사용해도 문제가 발생하지 않습니다. 세미콜론으로 모든 명령문을 종료하는 방법을 채택하는 것이 좋습니다. 이렇게하면 코드의 가독성이 향상 될뿐만 아니라 슬픔을 덜 수 있습니다. 세미콜론이 필요하고 지정되지 않은 경우 SQL Server가 생성하는 오류 메시지가 항상 명확하지는 않습니다.

그리고 가장 중요한 :

SQL Server 설명서는 세미콜론으로 T-SQL 문을 종료하지 않는 것이 더 이상 사용되지 않는 기능임을 나타냅니다. 이는 장기적인 목표는 향후 버전의 제품에 세미콜론을 사용하는 것입니다. 그것이 현재 필요하지 않은 곳에서도 모든 진술을 끝내는 습관을들이는 또 하나의 이유입니다.

출처 : Itzik Ben-Gan의 Microsoft SQL Server 2012 T-SQL 기본 사항 .


항상 사용해야하는 이유의 예는 ;다음 두 쿼리 (이 게시물 에서 복사 됨 )입니다.

BEGIN TRY
    BEGIN TRAN
    SELECT 1/0 AS CauseAnException
    COMMIT
END TRY
BEGIN CATCH
    SELECT ERROR_MESSAGE()
    THROW
END CATCH

여기에 이미지 설명을 입력하십시오

BEGIN TRY
    BEGIN TRAN
    SELECT 1/0 AS CauseAnException;
    COMMIT
END TRY
BEGIN CATCH
    SELECT ERROR_MESSAGE();
    THROW
END CATCH

여기에 이미지 설명을 입력하십시오


7
이것은 세미콜론 (따옴표로 백업) 을 사용해야한다는 강력한 논증 인 것 같지만 must 이있는 경우는 단 하나의 경우 입니다.
Gregor Thomas

3
@Gregor, 세미콜론 사용이 필수이며 not using them더 이상 사용되지 않는 기술이라고 발표되면 사용해야합니다. 그렇지 않으면 미래에 고통을 겪을 위험이 있습니다. 작업을 업그레이드 / 전환하지 않고 항상 SQL Server 2000으로 작업 할 계획이라면 안전합니다 :-)
gotqn

5
오른쪽, 해야한다 , 나는 동의한다. 그러나 그는 당신의 첫 번째 답변 은 must을 강조하지만 , 적어도 아직은 아닙니다.
Gregor Thomas

2
세미콜론이있는 예는 Incorrect syntax near 'THROW'.SQL Server 2008 (10.0.6241.0)을 생성하며, 이는 직장에서 처리해야하는 버전입니다. 사용 중단으로 인해 세미콜론을 사용하기 시작했습니다. 나는 그것이 2008 년에 대부분 문제가 될 것으로 예상하지 않는다.
Pilot_51

1
당신의 대답은 지금까지 최고입니다! 훨씬 더 많은지지를받을 가치가 있습니다.
스튜어트

22

이것을 올바르게 읽으면 세미콜론을 사용하여 TSQL 문을 끝내야합니다. http://msdn.microsoft.com/en-us/library/ms143729%28v=sql.120%29.aspx

편집 : 스크립트를 포맷하고 세미콜론을 추가하는 SSMS 2008R2 용 플러그인을 발견했습니다. 그래도 아직 베타 버전 인 것 같습니다 ...

http://www.tsqltidy.com/tsqltidySSMSAddin.aspx

편집 : ApexSQL이라는 훨씬 더 나은 무료 도구 / 플러그인을 찾았습니다 ... http://www.apexsql.com/


11

개인적인 의견 : 필요한 곳에만 사용하십시오. (필요한 목록은 위의 TheTXI의 답변을 참조하십시오.)

컴파일러를 필요로하지 않기 때문에, 당신은 할 수 있습니다 그것들을 모두 넣을 는 있지만 왜 그럴까요? 컴파일러는 어디를 잊었는지 알려주지 않으므로 일관되지 않은 사용으로 끝납니다.

[이 의견은 SQL Server에만 해당됩니다. 다른 데이터베이스에는보다 엄격한 요구 사항이있을 수 있습니다. 여러 데이터베이스에서 실행하기 위해 SQL을 작성하는 경우 요구 사항이 다를 수 있습니다.]

tpdi는 "스크립트에서 둘 이상의 문장을 보낼 때 필요하다"고 말했다. 실제로 정확하지 않습니다. 필요하지 않습니다.

PRINT 'Semicolons are optional'
PRINT 'Semicolons are optional'
PRINT 'Semicolons are optional';
PRINT 'Semicolons are optional';

산출:

Semicolons are optional
Semicolons are optional
Semicolons are optional
Semicolons are optional

1
이 토론에 대해 어떻게 생각하십니까? sqlservercentral.com/Forums/Topic636549-8-1.aspx (계정이없는 경우 bugmenot@bugmenot.com : bugmenot을 사용할 수 있음)
Anwar Pinto

2
본인은 이것이 귀하의 의견 일 뿐이라는 점을 분명히 인정했지만 Microsoft 문서 및 ANSI 표준과 충돌하기 때문에 좋은 답변이라고 생각하지 않습니다. 의견 에서이 의견이 더 좋을 것이라고 생각합니다. (당신을 강타하려고하지 마십시오, 당신은 세미콜론 사용에 대한 귀하의 의견에 완전히 권리가 있습니다!)
izzy

4

나는 여전히 T-SQL에 대해 배울 것이 많지만 트랜잭션에 대한 코드를 작성하고 (스택 오버 플로우 및 기타 사이트의 예제를 기반으로 한 코드) 세미콜론이 필요하고 누락 된 경우를 발견했습니다. 명령문이 전혀 실행되지 않고 오류가 발생하지 않습니다. 이것은 위의 답변에서 다루지 않은 것 같습니다. (MS SQL Server 2012를 사용하고있었습니다.)

거래가 내가 원하는 방식으로 작동하게 한 후에, 시도 캐치를 배치하기로 결정하여 오류가 있으면 롤백됩니다. 이 작업을 수행 한 후에 만 ​​트랜잭션이 커밋되지 않았습니다 (SSMS는 커밋되지 않은 트랜잭션이 있다는 사실을 알려주는 좋은 메시지로 창을 닫으려고 할 때이를 확인합니다.

그래서 이거

COMMIT TRANSACTION 

BEGIN TRY / END TRY 블록 외부에서는 트랜잭션을 커밋하는 데 문제가 없었지만 블록 내부에서는

COMMIT TRANSACTION;

오류나 경고가 제공되지 않으며 쿼리 탭을 닫을 때까지 트랜잭션이 아직 커밋되지 않았다는 표시가 없습니다.

다행히도 이것은 큰 문제를 일으켜 문제가 있음을 즉시 알 수 있습니다. 불행하게도 오류 (구문 또는 기타)가보고되지 않았기 때문에 문제가 무엇인지 즉시 알 수 없었습니다.

반대로 ROLLBACK TRANSACTION은 세미콜론이 있거나없는 BEGIN CATCH 블록에서 동일하게 작동하는 것 같습니다.

이것에 대한 논리가있을 수 있지만 임의의 원더 랜드 느낌을 느낍니다.


이것의 가능한 원인 중 하나 COMMIT TRANSACTION는 선택적인 트랜잭션 / 저장 지점 이름 을 허용하기 때문입니다 (무시할 것임). 세미콜론을 종료하지 않으면 COMMIT TRANSACTION코드의 의미를 근본적으로 변경할 수있는 식별자로 구문 분석 할 경우 다음 기호를 사용할 수 있습니다. 이로 인해 오류가 발생하면 CATCH실행되지 않은 채 트리거 될 수 있습니다 COMMIT. 반대로 ROLLBACK TRANSACTION이와 같은 선택적 식별자도 허용 하지만 구문 분석시 오류가 발생하면 트랜잭션이 롤백 될 가능성이 높습니다.
Jeroen Mostert

3

: 세미콜론 커서 작업과 함께 사용되어서는 안된다는 표시 OPEN, FETCH, CLOSEDEALLOCATE . 방금 이것으로 몇 시간을 낭비했습니다. 나는 BOL을 면밀히 살펴 보았고 [;]가이 커서 명령문의 구문에 표시되지 않음을 알았습니다 !!

그래서 나는 가지고 있었다 :

OPEN mycursor;

이로 인해 16916 오류가 발생했습니다.

그러나:

OPEN mycursor

일했다.


2
나는 이것이 옳지 않다고 생각합니다. BOL은 명령문 구문에서 세미콜론을 언급하는 데 일관성이 없으므로 SELECT를 살펴보십시오. 또한 OPEN someCursor를 보았습니다. ..., FETCH CLOSE 및 DEALLOCATE에 대한 동일한 벌금을, 작업
발렌티노 Vranken

파서에 버그가 있음을 제안합니다. 어떤 버전의 SQL Server를 사용하고 있습니까?
스튜어트

2

Transact-SQL 구문 규칙 (Transact-SQL) (MSDN) 에 따르면

Transact-SQL 문 종결 자 이 버전의 SQL Server에서는 대부분의 명령문에 세미콜론이 필요하지 않지만 향후 버전에서는 세미콜론이 필요합니다.

(또한 @gerryLowry의 의견 참조)


0

다른 명령문이 포함 된 배치에서 DISABLE 또는 ENABLE TRIGGER 문을 사용하는 경우 명령문 바로 앞의 명령문은 세미콜론으로 끝나야합니다. 그렇지 않으면 구문 오류가 발생합니다. 나는 이것으로 머리를 찢었다. 그리고 나중에, 나는이 MS Connect 아이템에 대해 같은 것을 발견했다. 수정되지 않으므로 닫힙니다.

여기를 참조 하십시오


0

참고 :이 질문은 작성된대로 질문에 대답하지만 언급 된 문제에는 해당되지 않습니다. 사람들이 검색하므로 여기에 추가

세미콜론은 또한 WITH재귀 CTE 문에서 사용됩니다 .

;WITH Numbers AS
(
    SELECT n = 1
    UNION ALL
    SELECT n + 1
    FROM Numbers
    WHERE n+1 <= 10
)
SELECT n
FROM Numbers

이 쿼리는 정수로 구성된 Numbers라는 CTE를 생성합니다 [1..10]. 값이 1 인 테이블 만 작성한 다음 10에 도달 할 때까지 반복합니다.


8
기술적으로 '전과'가 아니라 이전의 모든 일 이후. with가 배치에서 첫 번째 명령문 인 경우 세미콜론이 필요하지 않습니다.
Tor Haugen

그것은되지 함께 이전에 사용. 이것은 이전 명령문을 종료하는 세미콜론입니다. 세미콜론이 필요한 시나리오이기 때문에 일부 사람들은 세미콜론이 여기에 있어야한다고 결정한 것 같습니다. 이 사람들이 이것이 세미콜론으로 끝나는 문장 보다 항상 우수하다고 결정한 이유는 모르겠습니다.
스튜어트

0

SQLServer에서 임의의 Command Timeout 오류가 발생하는 경우 CommandText 문자열 끝에서 세미콜론을 제거하십시오.

나는 이것이 어디서나 문서화되는지 또는 버그인지는 모르지만, 그것이 일어나고 나는 쓴 경험에서 이것을 배웠다.

SQLServer 2008을 사용하여 확인 가능하고 재현 가능한 예가 있습니다.

일명-> 실제로는 데이터베이스에 하나의 명령문을 보내는 경우에도 항상 종결자를 포함시킵니다.


마지막에 세미콜론이 있는지 여부에 관계없이 쿼리에 대한 시간 초과가 발생하는 경우 의미 론적으로 관련이없는 것을 포함하여 정확한 쿼리 텍스트 에 일치시켜 캐시되므로 다른 실행 계획이 있기 때문에 거의 확실하게 발생합니다 공백, 주석 및 종결 세미콜론과 같은 것들. 세미콜론 자체는 타이밍 문제를 일으키는 데 완전히 결백합니다.
Jeroen Mostert

-2

세미콜론이 항상 복합 SELECT 문에서 작동하지는 않습니다.

이 두 가지 다른 버전의 간단한 복합 SELECT 문을 비교하십시오.

코드

DECLARE @Test varchar(35); 
SELECT @Test=
    (SELECT 
        (SELECT 
            (SELECT 'Semicolons do not always work fine.';););); 
SELECT @Test Test;

보고

Msg 102, Level 15, State 1, Line 5
Incorrect syntax near ';'.

그러나 코드

DECLARE @Test varchar(35)
SELECT @Test=
    (SELECT 
        (SELECT 
            (SELECT 'Semicolons do not always work fine.'))) 
SELECT @Test Test

보고

Test
-----------------------------------
Semicolons do not always work fine.

(1 row(s) affected)

11
[1 년 후] : 와우 ​​나는 아직이 답변에 대해 아무도 언급하지 않았다! 물론 작동하지 않습니다. 세미콜론은 명령문 구분 기호이므로 세미콜론이있는 코드는 다음과 같습니다. 1- SELECT @ Test = (SELECT (SELECT (SELECT '세미콜론은 항상 제대로 작동하지 않습니다.');--이것은 정확하지 않습니다 진술 2-);-이 둘도 3-);-둘 중 어느 것도 4-);
PhpLou

1
세미콜론 만 사용하여 명령문 을 종료 합니다 . 부속 조회는 명령문이 아닙니다. 명령문은 순서대로 실행되는 것입니다. 귀하의 예에는 다음과 같은 세 가지 진술이 있습니다. 1. DECLARE @ Test varchar (35) 2. SELECT @ Test = (SELECT (SELECT (SELECT '세미콜론은 항상 제대로 작동하지 않습니다.'))) 3. SELECT @ Test Test
Stewart
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.