Khi nào tôi cần sử dụng dấu chấm phẩy so với dấu gạch chéo trong Oracle SQL?


179

Chúng tôi đã có một số cuộc tranh luận trong tuần này tại công ty của tôi về cách chúng tôi nên viết các tập lệnh SQL của chúng tôi.

Bối cảnh: Cơ sở dữ liệu của chúng tôi là Oracle 10g (sớm nâng cấp lên 11). Nhóm DBA của chúng tôi sử dụng SQLPlus để triển khai các tập lệnh của chúng tôi để sản xuất.

Bây giờ, chúng tôi đã có một triển khai gần đây đã thất bại vì nó đã sử dụng cả dấu chấm phẩy và dấu gạch chéo ( /). Dấu chấm phẩy nằm ở cuối mỗi câu và dấu gạch chéo nằm giữa các câu.

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

Có một số kích hoạt được thêm vào sau trong tập lệnh, một số khung nhìn được tạo cũng như một số thủ tục được lưu trữ. Có cả hai ;/khiến cho mỗi câu lệnh chạy hai lần gây ra lỗi (đặc biệt là trên các phần chèn, cần phải là duy nhất).

Trong SQL Developer, điều này không xảy ra, trong TOAD, điều này không xảy ra. Nếu bạn chạy một số lệnh nhất định, chúng sẽ không hoạt động nếu không có /chúng.

Trong PL / SQL nếu bạn có chương trình con (DECLARE, BEGIN, END) thì dấu chấm phẩy được sử dụng sẽ được coi là một phần của chương trình con, do đó bạn phải sử dụng dấu gạch chéo.

Vì vậy, câu hỏi của tôi là: Nếu cơ sở dữ liệu của bạn là Oracle, cách viết kịch bản SQL của bạn là gì? Vì bạn biết rằng DB của bạn là Oracle nên bạn luôn sử dụng /?


1
Trong trường hợp ai đó đang thực hiện xuất cơ sở dữ liệu với SQLDeveloper, có một hộp kiểm gọi là "Terminator" mà khi được chọn sẽ sử dụng dấu chấm phẩy để chấm dứt mỗi câu lệnh. Tùy chọn này được chọn theo mặc định. Bỏ chọn để xóa dấu chấm phẩy và để tránh thực thi câu lệnh trùng lặp
Ruslans Uralovs

7
Chỉ cần vô tình làm trôi chủ đề cũ này đến chết, tôi sẽ đề cập rằng ngôn ngữ SQL không có dấu chấm phẩy. Nó chỉ đơn thuần là ký tự kết thúc mặc định trong SQL * Plus (bạn có thể đặt sqlterminatorthành !nếu bạn muốn) và quy ước này có xu hướng được theo sau bởi các công cụ khác. Tuy nhiên, ngôn ngữ PL / SQL sử dụng dấu chấm phẩy làm thành phần cú pháp bắt buộc.
William Robertson

Câu trả lời:


31

Đó là vấn đề ưu tiên, nhưng tôi thích thấy các tập lệnh luôn sử dụng dấu gạch chéo - theo cách này tất cả các "đơn vị" công việc (tạo đối tượng PL / SQL, chạy khối ẩn danh PL / SQL và thực thi câu lệnh DML) chọn ra dễ dàng hơn bằng mắt.

Ngoài ra, nếu cuối cùng bạn chuyển sang một thứ như Ant để triển khai, nó sẽ đơn giản hóa định nghĩa của các mục tiêu để có một dấu phân cách câu lệnh nhất quán.


1
câu trả lời này không giải thích lý do /hoặc ;xem câu trả lời của @a_horse_with_no_name hoặc @Mr_Moneybag để biết thêm ngữ cảnh
Kay

333

Tôi biết đây là một chủ đề cũ, nhưng tôi chỉ vấp phải nó và tôi cảm thấy điều này chưa được giải thích hoàn toàn.

Có một sự khác biệt rất lớn trong SQL * Plus giữa ý nghĩa của a /và a ;vì chúng hoạt động khác nhau.

Kết ;thúc một câu lệnh SQL, trong khi đó /thực thi bất cứ điều gì trong "bộ đệm" hiện tại. Vì vậy, khi bạn sử dụng a ; một /câu lệnh thực sự được thực thi hai lần.

Bạn có thể dễ dàng thấy rằng sử dụng một /sau khi chạy một câu lệnh:

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

Trong trường hợp này, người ta thực sự nhận thấy lỗi.


Nhưng giả sử có một tập lệnh SQL như thế này:

drop table foo;
/

Và điều này được chạy từ bên trong SQL * Plus, điều này sẽ rất khó hiểu:

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

Điều /này chủ yếu được yêu cầu để chạy các câu lệnh được nhúng ;như một CREATE PROCEDUREcâu lệnh.


2
@amis, tôi mới biết về Oracle và gặp vấn đề tương tự. Câu hỏi này rất hữu ích, nhưng tất cả các câu trả lời đã đưa ra lời giải thích về "tại sao" không phải là "cách tốt nhất" để làm việc hoặc một cách nào đó để giải quyết vấn đề này. Vì vậy, nếu tôi hiểu đúng, không có cách nào để chỉ có một tập lệnh và giữ nó có thể sử dụng được cho tất cả các công cụ ... hoặc bạn có khám phá ra một cách nào đó không?
ceinmart

5
@ceinmart: "cách tốt nhất" là xác định một (và chỉ một) công cụ để thực thi các tập lệnh SQL - và "tính chính xác" của tập lệnh được xác thực bằng công cụ đó. Tương tự như có một trình biên dịch cho ngôn ngữ lập trình của bạn hoặc một phiên bản cụ thể của môi trường thời gian chạy của bạn (Java 7, .Net 4.0, PHP 5.x, ...)
a_horse_with_no_name

1
Câu trả lời tốt. Có phải chỉ mình tôi hay Oracle ngớ ngẩn và cổ xưa so với các DB khác? Tôi đã sử dụng rất nhiều Sybase và nó có vẻ trực quan hơn nhiều.
giật gân

1
@Stationout: tốt, nếu bạn muốn chạy các câu lệnh có chứa dấu phân cách mặc định ( ;) thì bạn cần tìm cách chỉ định một dấu phân cách thay thế
a_horse_with_no_name

97

Tôi muốn làm rõ thêm một số sử dụng giữa ;/

Trong SQLPLUS:

  1. ; có nghĩa là "chấm dứt câu lệnh hiện tại, thực thi nó và lưu trữ nó vào bộ đệm SQLPLUS"
  2. <newline>sau câu lệnh DML (SELECT, UPDATE, INSERT, ...) hoặc một số loại câu lệnh DDL (Tạo bảng và dạng xem) (không chứa ;), có nghĩa là, lưu trữ câu lệnh vào bộ đệm nhưng không chạy nó.
  3. /sau khi nhập câu lệnh vào bộ đệm (có khoảng trống <newline>) có nghĩa là "chạy DML hoặc DDL hoặc PL / SQL trong bộ đệm.
  4. RUNhoặc Rlà một lệnh sqlsplus để hiển thị / xuất SQL trong bộ đệm và chạy nó. Nó sẽ không chấm dứt một câu lệnh SQL.
  5. / trong quá trình nhập DML hoặc DDL hoặc PL / SQL có nghĩa là "chấm dứt câu lệnh hiện tại, thực thi nó và lưu trữ nó vào bộ đệm SQLPLUS"

LƯU Ý: Vì SQLPLUS được sử dụng ;để kết thúc một câu lệnh ;mà SQLPLUS không thể sử dụng để có nghĩa là "chấm dứt câu lệnh hiện tại, thực thi nó và lưu trữ nó vào bộ đệm SQLPLUS" vì chúng tôi muốn toàn bộ khối PL / SQL hoàn toàn nằm trong khối đệm, sau đó thực hiện nó. Các khối PL / SQL phải kết thúc bằng:

END;
/

22

Hầu như tất cả các triển khai của Oracle đều được thực hiện thông qua SQL * Plus (công cụ dòng lệnh nhỏ kỳ lạ mà DBA của bạn sử dụng). Và trong SQL * Plus, một dấu gạch chéo đơn lẻ về cơ bản có nghĩa là "thực hiện lại lệnh SQL hoặc PL / SQL cuối cùng mà tôi vừa thực hiện".

Xem

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

Nguyên tắc chung là sử dụng dấu gạch chéo với những thứ làm BEGIN .. ENDhoặc nơi bạn có thể sử dụng CREATE OR REPLACE.

Đối với các chèn cần sử dụng duy nhất

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

Theo hiểu biết của tôi, tất cả các câu lệnh SQL không cần dấu gạch chéo vì chúng sẽ tự động chạy ở cuối dấu chấm phẩy, bao gồm các câu lệnh DDL, DML, DCL và TCL.

Đối với các khối PL / SQL khác, bao gồm Quy trình, Hàm, Gói và Kích hoạt, vì chúng là các chương trình nhiều dòng, Oracle cần một cách để biết khi nào nên chạy khối, vì vậy chúng tôi phải viết một dấu gạch chéo về phía trước của mỗi khối để Hãy để Oracle chạy nó.


1

Tôi chỉ sử dụng dấu gạch chéo một lần ở cuối mỗi tập lệnh, để nói với sqlplus rằng không có nhiều dòng mã hơn. Ở giữa tập lệnh, tôi không sử dụng dấu gạch chéo.


Vì vậy, bạn có đặt hàng những thứ yêu cầu / (chẳng hạn như chương trình con và kích hoạt) ở cuối không? Điều gì nếu bạn có nhiều kích hoạt? Tôi đã chạy thử nghiệm và chỉ có cái đầu tiên thực thi trừ khi nó có / giữa mỗi cái. Tui bỏ lỡ điều gì vậy?
amischiefr

Tôi cố gắng tránh nó (nếu có thể), nhưng nếu tôi không thể (như trong trình kích hoạt), tôi sử dụng dấu chấm phẩy và dấu gạch chéo chính xác như được sử dụng trong các tập lệnh chính thức tạo ra các lược đồ mẫu của oracle: download.oracle.com/docs /cd/B19306_01/server.102/b14198/ Từ Đối với vấn đề chèn, tôi cố gắng tách các tập lệnh tạo đối tượng khỏi những người điền vào bảng.
Jonathan

1
Xin lỗi, nhưng điều này không trả lời câu hỏi.
DerMike
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.