Oracle SQL에서 세미콜론과 슬래시를 언제 사용해야합니까?


179

우리는 이번 주에 회사에서 SQL 스크립트 작성 방법에 대해 토론했습니다.

배경 : 데이터베이스는 Oracle 10g입니다 (곧 11로 업그레이드). DBA 팀은 스크립트를 프로덕션에 배포하기 위해 SQLPlus를 사용합니다.

이제 세미콜론과 슬래시 ( /)를 모두 사용했기 때문에 최근 배포에 실패했습니다 . 세미콜론은 각 문장의 끝에 있었고 슬래시는 문장 사이에있었습니다.

alter table foo.bar drop constraint bar1;
/
alter table foo.can drop constraint can1;
/

스크립트에서 나중에 추가 된 트리거, 일부 뷰 및 일부 저장 프로 시저가 추가되었습니다. ;/문 을 모두 사용하면 각 문이 두 번 실행되어 오류가 발생했습니다 (특히 고유 한 삽입에서).

SQL Developer에서는 이런 일이 발생하지 않으며 TOAD에서는 이런 일이 발생하지 않습니다. 특정 명령을 실행하면 명령이 없으면 작동하지 않습니다 /.

PL / SQL에서 서브 프로그램 (DECLARE, BEGIN, END)이있는 경우 사용 된 세미콜론은 서브 프로그램의 일부로 간주되므로 슬래시를 사용해야합니다.

내 질문은 이것입니다 : 데이터베이스가 Oracle 인 경우 SQL 스크립트를 작성하는 올바른 방법은 무엇입니까? DB가 Oracle이라는 것을 알고 있으므로 항상 /?


1
누군가 SQLDeveloper로 데이터베이스 익스포트를 수행하는 경우 "터미네이터"라는 체크 박스가 있는데,이 옵션을 선택하면 세미콜론을 사용하여 각 명령문을 종료합니다. 이 옵션은 기본적으로 선택되어 있습니다. 세미콜론을 제거하고 중복 명령문 실행을 피하려면 선택 취소하십시오.
Ruslans Uralovs

7
이 오래된 스레드를 무의식적으로 막기 위해 SQL 언어에는 세미콜론이 없다고 언급하겠습니다. 그것은 단지 SQL * 플러스에서 기본 종료 문자 (사용자가 설정할 수 있습니다 sqlterminator!당신이 좋아하는 경우)이 규칙은 다른 도구 다음되는 경향이있다. 그러나 PL / SQL 언어는 세미콜론을 필수 구문 요소로 사용합니다.
William Robertson

답변:


31

선호의 문제이지만 슬래시를 일관되게 사용하는 스크립트를 선호합니다.이 방식으로 모든 작업 단위 (PL / SQL 객체 생성, PL / SQL 익명 블록 실행 및 DML 문 실행)가 가능합니다. 눈으로 더 쉽게 골랐습니다.

또한 결국 배포를 위해 Ant와 같은 것으로 이동하면 대상 정의를 단순화하여 일관된 명령문 구분 기호를 갖습니다.


1
이 답변은 이유를 설명하지 /않거나 ;자세한 내용은 @a_horse_with_no_name 또는 @Mr_Moneybags의 답변을 참조하십시오
Kay

333

나는 이것이 오래된 실이라는 것을 알고 있지만 방금 넘어졌으며 이것이 완전히 설명되지 않았다고 생각합니다.

a /와 a 의 의미는 ;다르게 작동하므로 SQL * Plus에는 큰 차이가 있습니다.

;단부는 SQL 명령문의 반면, /현재에 실행하는대로 "버퍼". 당신은을 사용할 때 그래서 ; / 문이 실제로 두 번 실행됩니다.

/명령문을 실행 한 후 다음 을 사용하면 쉽게 알 수 있습니다 .

SQL*Plus: Release 11.2.0.1.0 Production on Wed Apr 18 12:37:20 2012

Copyright (c) 1982, 2010, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning and OLAP options

SQL> drop table foo;

Table dropped.

SQL> /
drop table foo
           *
ERROR at line 1:
ORA-00942: table or view does not exist

이 경우 실제로 오류를 알 수 있습니다.


그러나 다음과 같은 SQL 스크립트가 있다고 가정합니다.

drop table foo;
/

그리고 이것은 SQL * Plus 내에서 실행되며 매우 혼란 스럽습니다.

SQL*Plus: Release 11.2.0.1.0 Production on Wed Apr 18 12:38:05 2012

Copyright (c) 1982, 2010, Oracle.  All rights reserved.


Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning and OLAP options

SQL> @drop

Table dropped.

drop table foo
           *
ERROR at line 1:
ORA-00942: table or view does not exist

/주로 내장 한 문을 실행하기 위해 필요한 ;유사한 CREATE PROCEDURE문을.


2
@amis, 저는 Oracle을 처음 사용하고 같은 문제에 봉착했습니다. 이 질문은 매우 유용하지만 모든 답변은 "최상의 방법"이 아닌 "이유"에 대한 설명 또는이 문제를 해결하는 방법에 대한 설명을 제공했습니다. 따라서 내가 올바르게 이해하면 하나의 스크립트 만 가지고 모든 도구에 사용할 수있는 방법이 없습니다 ... 또는 어떤 방법을 발견합니까?
ceinmart

5
@ceinmart : "가장 좋은 방법"은 SQL 스크립트를 실행할 하나의 도구를 정의하는 것입니다. 스크립트의 "정확성"은 해당 도구를 사용하여 검증됩니다. 프로그래밍 언어를위한 하나의 컴파일러 또는 하나의 특정 버전의 런타임 환경 (Java 7, .Net 4.0, PHP 5.x, ...)과
유사

1
좋은 대답입니다. 그것은 나입니까 아니면 Oracle 구피와 다른 DB와 비교할 때 구식입니까? 나는 많은 Sybase를 사용했으며 훨씬 직관적입니다.
splashout

1
@splashout : 당신이 기본 구분 기호를 (포함 문을 실행하려면 아니라 ;) 당신은 대체 구분 지정하는 방법 찾아야
a_horse_with_no_name

97

나는 사이에 더 많은 사용을 분명히하고 싶었다 ;./

SQLPLUS에서 :

  1. ; "현재 명령문을 종료하고 실행하여 SQLPLUS 버퍼에 저장"을 의미합니다.
  2. <newline>DML (SELECT, UPDATE, INSERT, ...) 문 또는 no를 포함하는 일부 유형의 DDL (Creating Tables and Views) 문 다음에 ;, 문을 버퍼에 저장하지만 실행하지는 않습니다.
  3. /버퍼에 명령문을 입력 한 후 (공백 포함 <newline>)는 " 버퍼 에서 DML 또는 DDL 또는 PL / SQL을 실행하는 것을 의미합니다.
  4. RUN또는 R버퍼에 SQL을 표시 / 출력하고 실행하기위한 sqlsplus 명령입니다. SQL 문을 종료하지 않습니다.
  5. / DML 또는 DDL 또는 PL / SQL을 입력하는 동안 "현재 명령문을 종료하고 실행하여 SQLPLUS 버퍼에 저장"을 의미합니다.

참고 : 때문에 ;문을 종료 PL / SQL에 사용되는은 ;우리가 전체 PL / SQL 블록이 완전히되고 싶어하기 때문에 의미 "현재 문을 종료를 실행하고 SQLPLUS 버퍼에 저장"을 SQLPLUS에서 사용할 수 없습니다 버퍼, 실행하십시오. PL / SQL 블록은 다음과 같이 끝나야합니다.

END;
/

22

거의 모든 Oracle 배포는 SQL * Plus (DBA가 사용하는 이상한 작은 명령 줄 도구)를 통해 수행됩니다. 그리고 SQL * Plus에서 슬래시는 기본적으로 "방금 실행 한 마지막 SQL 또는 PL / SQL 명령을 다시 실행"을 의미합니다.

보다

http://ss64.com/ora/syntax-sqlplus.html

경험상 BEGIN .. END또는 할 수있는 일에 슬래시를 사용하는 것이 일반적입니다 CREATE OR REPLACE.

고유하게 사용해야하는 인서트

INSERT INTO my_table ()
SELECT <values to be inserted>
FROM dual
WHERE NOT EXISTS (SELECT 
                  FROM my_table
                  WHERE <identify data that you are trying to insert>)

14

내 이해에 따르면 모든 SQL 문은 DDL, DML, DCL 및 TCL 문을 포함한 세미콜론의 끝에서 자동으로 실행되므로 슬래시가 필요하지 않습니다.

프로 시저, 함수, 패키지 및 트리거를 포함한 다른 PL / SQL 블록의 경우 여러 라인 프로그램이므로 Oracle은 블록을 실행할시기를 알 수있는 방법이 필요하므로 각 블록의 끝에 슬래시를 작성해야합니다. 오라클이 운영하게하십시오.


1

각 스크립트의 끝에서 한 번만 슬래시를 사용하여 더 많은 코드 줄이 없다는 것을 sqlplus에 알립니다. 스크립트 중간에 슬래시를 사용하지 않습니다.


따라서 마지막에 / (서브 프로그램 및 트리거와 같은)가 필요한 항목을 주문합니까? 트리거가 여러 개인 경우 어떻게합니까? 테스트를 실행했으며 각 테스트 사이에 /가 없으면 첫 번째 테스트 만 실행됩니다. 뭔가 빠졌습니까?
amischiefr

나는 (가능하다면) 피하려고 노력하지만 (트리거 에서처럼) 할 수 없다면 oracle의 샘플 스키마를 생성하는 공식 스크립트에서 사용되는 세미콜론과 슬래시를 사용합니다 : download.oracle.com/docs /cd/B19306_01/server.102/b14198/… 삽입 문제의 경우, 테이블을 채우는 스크립트와 오브젝트를 작성하는 스크립트를 분리하려고합니다.
Jonathan

1
죄송하지만 질문에 대한 답변은 아닙니다.
DerMike
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.