공백, 세미콜론 및 슬래시가 포함 된 SQLPlus로 스크립트 실행


15

때때로 SQL Developer 또는 Toad에서 잘 실행되는 스크립트를 얻지 만 SQL * Plus에서 성공적으로 실행하려면 수정이 필요합니다. 다음은 각각 빈 줄, 세미콜론 및 슬래시가있는 여러 명령문을 포함하는 최악의 예입니다.

INSERT INTO t1 VALUES ('a

;
/
');

INSERT INTO t1 VALUES ('b

;
/
');

DELETE FROM t1 WHERE c1 = 'c

;
/
';

여러 가지 이유로 이러한 명령문은 SQL * Plus에서 실행해야합니다. 빈 줄은 간단하게 해결하기 쉽습니다 ...

set sqlblanklines on

나는 sqlterminator코드를 변경하거나 끌 수 있다는 것을 알고 있지만 둘 다 코드를 수정해야하며 전자는 문제를 해결하지 않고 문제를 옮기고 내장 슬래시 문제를 해결하지는 않습니다.

가장 좋은 대답은 환경을 어떤 식 으로든 변경하여 (sqlblanklines와 같이) 이러한 명령문을 수정하지 않고 실행할 수있는 방법입니다. 이것이 불가능하다면, 프로그래밍 방식으로 스크립트를 수정하는 방법이있을 것입니다. 수동 변경을 피하려고합니다.


이 문제는 SQLPLUS의 명령 행 실행을 사용할 때 쉽게 발생할 수 있습니다. SQLPLUS 프로그램 내부에있는 동안 명령 행 편집기도 여전히 활성 상태입니다. 결과적으로, 명령 행 편집기와 관련된 항목 (공백은 명령 / 변수로 해석되고 세미콜론은 명령의 끝으로 표시됩니다). 따라서 비밀번호에 '@'이 있으면 로그인하려고 할 때 마음이 아프게됩니다 (@의 오른쪽에있는 모든 것이 DB 이름으로 표시됨). 주요 배포 과정에서 TOAD를 통해 물건을 배포해야하는 빈 공간 문제가 발견되었습니다. SQLPLUS는 쓸모가 없었습니다
TomV

당신의 생각에 감사합니다. 그래서, 내가 요청한 것이 불가능하다는 당신의 대답은 명확합니까?
레이 리펠

문자열 내 캐리지 리턴을 chr (10)로 변환 할 수 있습니까? insert가 한 줄에 나열되어 있습니까?
크리스 색슨

@ChrisSaxon 할 수는 있지만이 문제는 인코딩 해야하는 반환과 구문의 일부로 단독으로 남겨야하는 반환을 구별하는 방법입니다. 이 작업을 수행 할 수있는 방법이 있으면 답변으로 게시하십시오.
레이 리펠

답변:


8

login.sql을 사용하여 대부분의 작업을 수행 할 수 있습니다. login.sql은-놀라운-로그인 중에 실행되며 SQLPATH 또는 현재 디렉토리에서로드됩니다. 예를 들어, 당신은 실제로 최악의 경우를 선택했습니다.

문제는 sqlterminator입니다. 거기에 넣은 내용에 상관없이 슬래시는 무료 sqlterminator로 유지됩니다. 그 다음으로 sqlplus는 먼저 sqlterminator를 스캔하고 문자열 종결 자로 스캔하기 전에이를 수행합니다. 당신이 나에게 묻는다면 버그. 슬래시가 별도의 행에 있지 않은 한 문자열에서 슬래시를 사용할 수 있습니다. sqlplus가 sqlterminator로 지정된 문자를 찾으면 다른 모든 것을 무시하고 읽기를 중지합니다.

슬래시가 한 줄에 있지 않은 한 슬래시를 처리 할 수 ​​있습니다.

login.sql은 다음을 포함합니다 :

prompt run login.sql
show sqlterminator
show sqlblanklines
set sqlblanklines on
set sqlterminator ';'
show sqlterminator
show sqlblanklines
prompt ready login.sql
set echo on

leigh.sql은 다음을 포함합니다 :

INSERT INTO t1 VALUES ('fail bc semicolon
a;a
/
'); 

INSERT INTO t1 VALUES ('fail bc solo /


aa
/
');

INSERT INTO t1 VALUES ('ok / not solo


aa
/a
');

DELETE FROM t1 WHERE a = 'c


a/
';

스크립트를 실행하십시오.

sqlplus leigh/leigh@orcl @leigh
SQL*Plus: Release 10.2.0.4.0 - Production on Thu Aug 9 22:36:20 2012

Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.


Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Data Mining and Real Application Testing options

run login.sql
sqlterminator ";" (hex 3b)
sqlblanklines OFF
sqlterminator ";" (hex 3b)
sqlblanklines ON
ready login.sql
SQL> INSERT INTO t1 VALUES ('fail bc semicolon
  2  a;a
  3  /
ERROR:
ORA-01756: quoted string not properly terminated


SQL> ');
SP2-0042: unknown command "')" - rest of line ignored.
SQL> 
SQL> INSERT INTO t1 VALUES ('fail bc solo /
  2  
  3  
  4  aa
  5  /
ERROR:
ORA-01756: quoted string not properly terminated


SQL> ');
SP2-0042: unknown command "')" - rest of line ignored.
SQL> 
SQL> INSERT INTO t1 VALUES ('ok / not solo
  2  
  3  
  4  aa
  5  /a
  6  ');

1 row created.

SQL> 
SQL> DELETE FROM t1 WHERE a = 'c
  2  
  3  
  4  a/
  5  ';

0 rows deleted.

시작 / 종료 블록으로 바이올린을 칠 필요가 없습니다. 문자열의 위치에 관계없이 명령 내부에서 sqlterminator를 처리 할 수 ​​없습니다. 문자열의 줄에서 슬래시가있는 줄은 단독으로 처리 할 수 ​​없습니다.


1
증거 감사합니다. 이미 login.sql 파일 설정을 비슷하게 사용하고 있습니다. 그래서 기본적으로 이것은 내가하고 싶은 이유를 수행 할 수 없음을 확인합니다.
레이 리펠

1
약간의 변형은 설정을 수행하고 실제 스크립트를 호출하는 러너 스크립트를 사용하는 것입니다. sqlplus leigh / leigh @ orcl @runner leigh가됩니다. login.sql보다 약간 더 유연합니다
ik_zelf

1

빈 줄과 세미콜론이있는 삽입 문은 BEGIN ... END 블록 안에 있으면 성공합니다. 이 변경은 스크립트를 사용하여 수행 할 수 있지만 즉시 실행하지 않고 블록 내에서 실행할 수없는 DDL 문이 포함되어 있으면 스크립트가 실패합니다.

이 솔루션은 또한 포함 / 문제를 해결하지 않습니다.


과거에는 sqlplus를 피하기 위해 perl / DBD 스크립트를 사용했습니다. 공유 행복 ...
Philᵀᴹ

@Phil 감사합니다. 그러나 SQLPlus는 99.9 %의 상황에서 제대로 작동하므로 다른 도구를 추가하지는 않겠습니다.
레이 리펠

1

내 해결 방법 :

         begin
             INSERT INTO t1 VALUES ('a

             ;
             ');
         end;
         /

body 문에서 명령 종결자가 무시되는 것처럼 보입니다.


이것이 DDL 문이나 내장 슬래시에 적합한 솔루션이 아닌 이유에 대한 대답을 참조하십시오.
레이 리펠

-1
set sqlterminator OFF
<...>
set sqlterminator ON

1
그리고 이것이 어떻게 도움이 될까요?
dezso
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.