Thực thi tập lệnh với SQLPlus chứa khoảng trắng, dấu chấm phẩy và dấu gạch chéo về phía trước


15

Thỉnh thoảng tôi sẽ nhận được một tập lệnh sẽ chạy tốt trong SQL Developer hoặc Toad, nhưng yêu cầu sửa đổi để được chạy thành công từ SQL * Plus. Dưới đây là một ví dụ tồi tệ nhất chứa nhiều câu lệnh với mỗi dòng trống, dấu chấm phẩy và dấu gạch chéo về phía trước:

INSERT INTO t1 VALUES ('a

;
/
');

INSERT INTO t1 VALUES ('b

;
/
');

DELETE FROM t1 WHERE c1 = 'c

;
/
';

Vì nhiều lý do, các câu lệnh này cần được chạy từ SQL * Plus. Các dòng trống dễ dàng giải quyết với một ...

set sqlblanklines on

Tôi biết rằng sqlterminatorcó thể thay đổi và / hoặc tắt, nhưng cả hai sẽ yêu cầu sửa đổi mã, trước đây di chuyển vấn đề mà không giải quyết nó và không giải quyết vấn đề gạch chéo được nhúng.

Câu trả lời tốt nhất sẽ là một cách để cho phép các câu lệnh này chạy mà không cần sửa đổi bằng cách thay đổi môi trường theo một cách nào đó (như sqlblanklines hiện). Nếu điều đó là không thể, thì có lẽ có một cách để lập trình sửa đổi các tập lệnh. Tôi đang cố gắng tránh những thay đổi thủ công.


Vấn đề này có thể dễ dàng xảy ra khi sử dụng thực thi dòng lệnh của SQLPLUS. Trong khi bạn đang ở trong chương trình SQLPLUS, trình soạn thảo dòng lệnh cũng vẫn hoạt động. Kết quả là, các mục có liên quan đến trình soạn thảo dòng lệnh (khoảng trắng được hiểu là lệnh / biến, dấu chấm phẩy được xem là kết thúc của lệnh). Đó là lý do tại sao có '@' trong mật khẩu không gây ra gì ngoài đau lòng khi bạn cố gắng đăng nhập (mọi thứ ở bên phải của @ được xem là tên của DB). Trong quá trình triển khai lớn, chúng tôi đã phát hiện ra các vấn đề với các khoảng trống buộc chúng tôi phải triển khai công cụ thông qua TOAD. SQLPLUS là vô dụng đối với
TomV

Cảm ơn bạn đã suy nghĩ của bạn. Vì vậy, để làm rõ là câu trả lời của bạn rằng những gì tôi đang yêu cầu là không thể?
Leigh Riffel

Bạn có thể chuyển đổi trả về vận chuyển trong chuỗi thành chèn chr (10) được liệt kê trên một dòng không?
Chris Saxon

@ChrisSaxon Tôi có thể, nhưng vấn đề này là làm thế nào để phân biệt các trả về nên được mã hóa và các trả về cần được để lại một mình như một phần của cú pháp. Nếu bạn có một cách để làm điều này xin vui lòng gửi đây là một câu trả lời.
Leigh Riffel

Câu trả lời:


8

Bạn có thể làm hầu hết điều này bằng cách sử dụng login.sql. login.sql được thực thi trong thời gian - đáng ngạc nhiên - đăng nhập và được tải từ SQLPATH hoặc thư mục hiện tại của bạn. Đối với các ví dụ bạn đã đưa ra, bạn thực sự đã chọn trường hợp xấu nhất.

Vấn đề là sqlterminator. Bất cứ điều gì bạn đặt vào đó, dấu gạch chéo về phía trước được duy trì như một sqlterminator miễn phí. Bên cạnh đó, sqlplus đầu tiên quét tìm sqlterminator và thực hiện điều này trước khi quét đến bộ kết thúc chuỗi. Một lỗi nếu bạn hỏi tôi. Dấu gạch chéo phía trước có thể được sử dụng trong một chuỗi miễn là nó không đơn độc trên một dòng riêng biệt. Ngay khi sqlplus tìm thấy ký tự được chỉ định là sqlterminator, nó sẽ bỏ qua mọi thứ khác và dừng đọc.

Dấu gạch chéo phía trước có thể được xử lý, miễn là nó không đơn độc trên một dòng.

login.sql chứa:

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 chứa:

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/
';

chạy tập lệnh:

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.

Không cần phải nghịch ngợm với khối bắt đầu / kết thúc. Không thể xử lý lệnh sqlterminator bên trong lệnh, bất kể nó ở đâu, trong chuỗi hay không, không thể xử lý các dòng với dấu gạch chéo một mình trên một dòng trong chuỗi.


1
Cảm ơn bạn đã chứng minh. Tôi đã sử dụng một thiết lập tập tin login.sql tương tự. Vì vậy, về cơ bản điều này xác nhận rằng tại sao tôi muốn làm không thể được thực hiện.
Leigh Riffel

1
một biến thể nhỏ là sử dụng tập lệnh chạy thực hiện cài đặt và gọi tập lệnh thực. Sẽ trở thành sqlplus leigh / leigh @ orcl @runner leigh. Đó là một chút linh hoạt hơn so với login.sql
ik_zelf

1

Chèn các câu lệnh với các dòng trống và dấu chấm phẩy sẽ thành công nếu được đặt bên trong các khối BEGIN ... END. Thay đổi này có thể được thực hiện bằng cách sử dụng tập lệnh, nhưng tập lệnh sẽ thất bại nếu nó chứa các câu lệnh DDL không thể chạy trong một khối mà không thực thi ngay lập tức.

Giải pháp này cũng không giải quyết được vấn đề nhúng /.


Trước đây, tôi đã sử dụng tập lệnh perl / DBD để làm điều này để tránh sqlplus. Rất vui được chia sẻ ...
Philᵀᴹ

@Phil Cảm ơn bạn, nhưng SQLPlus hoạt động tốt trong 99,9% tình huống, vì vậy tôi không muốn thêm một công cụ khác vào hỗn hợp.
Leigh Riffel

1

Cách giải quyết của tôi:

         begin
             INSERT INTO t1 VALUES ('a

             ;
             ');
         end;
         /

Có vẻ như lệnh kết thúc bị bỏ qua bên trong tuyên bố cơ thể.


Xem câu trả lời của tôi để biết lý do tại sao đây không phải là một giải pháp tốt cho các câu lệnh DDL hoặc dấu gạch chéo được nhúng.
Leigh Riffel

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.