Kapan saya perlu menggunakan tanda titik koma vs garis miring pada Oracle SQL?

179

Kami telah memiliki beberapa perdebatan minggu ini di perusahaan saya tentang bagaimana kita harus menulis skrip SQL kami.

Latar Belakang: Basis data kami adalah Oracle 10g (segera ditingkatkan menjadi 11). Tim DBA kami menggunakan SQLPlus untuk menyebarkan skrip kami ke produksi.

Sekarang, kami memiliki penyebaran baru-baru ini yang gagal karena telah menggunakan titik koma dan garis miring ( /). Tanda titik koma ada di akhir setiap pernyataan dan garis miring berada di antara pernyataan.

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

Ada beberapa pemicu yang ditambahkan kemudian dalam skrip, beberapa tampilan dibuat serta beberapa prosedur tersimpan. Memiliki kedua ;dan /menyebabkan setiap pernyataan berjalan dua kali menyebabkan kesalahan (terutama pada sisipan, yang perlu unik).

Di SQL Developer ini tidak terjadi, di TOAD ini tidak terjadi. Jika Anda menjalankan perintah tertentu mereka tidak akan berfungsi tanpa /di dalamnya.

Dalam PL / SQL jika Anda memiliki subprogram (DECLARE, BEGIN, END) titik koma yang digunakan akan dianggap sebagai bagian dari subprogram, jadi Anda harus menggunakan garis miring.

Jadi pertanyaan saya adalah ini: Jika database Anda adalah Oracle, apa cara yang tepat untuk menulis skrip SQL Anda? Karena Anda tahu bahwa DB Anda adalah Oracle, haruskah Anda selalu menggunakannya /?

amischiefr
sumber
1
Jika seseorang melakukan ekspor basis data dengan SQLDeveloper ada kotak centang yang disebut "Terminator" yang ketika dipilih menggunakan tanda titik koma untuk mengakhiri setiap pernyataan. Opsi ini dipilih secara default. Batalkan pilihan untuk menghapus titik koma dan untuk menghindari eksekusi pernyataan rangkap
Ruslans Uralovs
7
Hanya untuk sia-sia belasan utas lama ini sampai mati, saya akan menyebutkan bahwa bahasa SQL tidak memiliki titik koma. Ini hanyalah karakter terminator default dalam SQL * Plus (Anda dapat mengatur sqlterminatoruntuk !jika Anda suka) dan konvensi ini cenderung diikuti oleh alat-alat lain. Namun, bahasa PL / SQL menggunakan titik koma sebagai elemen sintaks wajib.
William Robertson

Jawaban:

31

Ini masalah preferensi, tapi saya lebih suka melihat skrip yang secara konsisten menggunakan garis miring - dengan cara ini semua "unit" kerja (membuat objek PL / SQL, menjalankan blok anonim PL / SQL, dan menjalankan pernyataan DML) dapat berupa dipilih lebih mudah dengan mata.

Juga, jika Anda akhirnya pindah ke sesuatu seperti Semut untuk ditempatkan, itu akan menyederhanakan definisi target untuk memiliki pembatas pernyataan yang konsisten.

dpbradley
sumber
1
jawaban ini tidak menjelaskan mengapa /atau ;melihat jawaban @a_horse_with_no_name atau @Mr_Moneybags untuk lebih banyak konteks
Kay
333

Saya tahu ini adalah utas lama, tetapi saya baru saja menemukannya dan saya merasa ini belum dijelaskan sepenuhnya.

Ada perbedaan besar dalam SQL * Plus antara arti a /dan a ;karena mereka bekerja secara berbeda.

Yang ;mengakhiri pernyataan SQL, sedangkan /mengeksekusi apa pun yang ada di "buffer" saat ini. Jadi, ketika Anda menggunakan ; dan sebuah /pernyataan sebenarnya dieksekusi dua kali.

Anda dapat dengan mudah melihat bahwa menggunakan /setelah menjalankan pernyataan:

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

Dalam hal ini orang benar-benar memperhatikan kesalahan.


Tetapi dengan asumsi ada skrip SQL seperti ini:

drop table foo;
/

Dan ini dijalankan dari dalam SQL * Plus maka ini akan sangat membingungkan:

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

The /terutama diperlukan dalam rangka untuk menjalankan pernyataan yang telah tertanam ;seperti CREATE PROCEDUREpernyataan.

seekor kuda tanpa nama
sumber
2
@amis, saya baru di Oracle dan masuk ke masalah yang sama. Pertanyaan ini sangat berguna, tetapi semua jawaban memberikan penjelasan tentang "mengapa" bukan "cara terbaik" untuk bekerja atau cara untuk mengatasinya. Jadi, jika saya mengerti benar, tidak ada cara untuk hanya memiliki satu skrip dan tetap dapat digunakan untuk semua alat ... atau apakah Anda menemukan cara?
ceinmart
5
@ceinmart: "cara terbaik" adalah mendefinisikan satu (dan hanya satu) alat untuk menjalankan skrip SQL - dan "kebenaran" skrip divalidasi menggunakan alat itu. Mirip dengan memiliki satu kompiler untuk bahasa pemrograman Anda atau satu versi spesifik dari lingkungan runtime Anda (Java 7, .Net 4.0, PHP 5.x, ...)
a_horse_with_no_name
1
Jawaban yang bagus. Apakah hanya saya atau Oracle konyol dan kuno dibandingkan dengan DB lain? Saya telah menggunakan banyak Sybase dan sepertinya jauh lebih intuitif.
splashout
1
@splashout: yah, jika Anda ingin menjalankan pernyataan yang mengandung pembatas default ( ;) maka Anda perlu menemukan cara untuk menentukan pembatas alternatif
a_horse_with_no_name
97

Saya ingin mengklarifikasi lebih banyak penggunaan antara ;dan/

Dalam SQLPLUS:

  1. ; berarti "mengakhiri pernyataan saat ini, jalankan dan simpan ke buffer SQLPLUS"
  2. <newline>setelah pernyataan DML (SELECT, UPDATE, INSERT, ...) atau beberapa jenis pernyataan DDL (Membuat Tabel dan Tampilan) (yang tidak mengandung ;), itu artinya, menyimpan pernyataan itu ke buffer tetapi tidak menjalankannya.
  3. /setelah memasukkan pernyataan ke dalam buffer (dengan kosong <newline>) berarti "jalankan DML atau DDL atau PL / SQL di buffer.
  4. RUNatau Radalah perintah sqlsplus untuk menampilkan / menampilkan SQL dalam buffer dan menjalankannya. Itu tidak akan mengakhiri Pernyataan SQL.
  5. / selama memasukkan DML atau DDL atau PL / SQL berarti "mengakhiri pernyataan saat ini, jalankan dan simpan ke buffer SQLPLUS"

CATATAN: Karena ;digunakan untuk PL / SQL untuk mengakhiri pernyataan ;tidak dapat digunakan oleh SQLPLUS berarti "mengakhiri pernyataan saat ini, jalankan dan simpan ke buffer SQLPLUS" karena kami ingin seluruh blok PL / SQL sepenuhnya di buffer, lalu jalankan. Blok PL / SQL harus diakhiri dengan:

END;
/
Mr_Moneybags
sumber
22

Hampir semua penyebaran Oracle dilakukan melalui SQL * Plus (alat baris perintah kecil yang aneh yang digunakan DBA Anda). Dan dalam SQL * Plus sebuah slash tunggal pada dasarnya berarti "jalankan kembali perintah SQL atau PL / SQL terakhir yang baru saja saya jalankan".

Lihat

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

Aturan praktisnya adalah menggunakan tebasan dengan hal-hal yang dilakukan BEGIN .. ENDatau di mana Anda dapat menggunakannya CREATE OR REPLACE.

Untuk sisipan yang perlu digunakan secara unik

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>)
jva
sumber
14

Dari pemahaman saya, semua pernyataan SQL tidak perlu garis miring karena mereka akan berjalan secara otomatis di akhir titik koma, termasuk pernyataan DDL, DML, DCL dan TCL.

Untuk blok PL / SQL lainnya, termasuk Prosedur, Fungsi, Paket dan Pemicu, karena mereka adalah beberapa program garis, Oracle perlu cara untuk mengetahui kapan harus menjalankan blok, jadi kita harus menulis garis miring di akhir setiap blok untuk biarkan Oracle yang menjalankannya.

Jerry
sumber
1

Saya hanya menggunakan garis miring sekali pada akhir setiap skrip, untuk memberi tahu sqlplus bahwa tidak ada lagi baris kode. Di tengah naskah, saya tidak menggunakan garis miring.

Jonathan
sumber
Jadi, apakah Anda memesan hal-hal yang memerlukan / (seperti subprogram dan pemicu) di akhir? Bagaimana jika Anda memiliki banyak pemicu? Saya menjalankan tes dan hanya yang pertama dijalankan kecuali memiliki / antara masing-masing. Apakah saya melewatkan sesuatu?
amischiefr
Saya mencoba menghindarinya (jika mungkin), tetapi jika saya tidak bisa (seperti pada pemicu), saya menggunakan titik koma dan garis miring persis seperti yang digunakan dalam skrip resmi yang menghasilkan skema sampel oracle: download.oracle.com/docs /cd/B19306_01/server.102/b14198/... Untuk masalah sisipan, saya mencoba memisahkan skrip yang membuat objek dari orang-orang yang mengisi tabel.
Jonathan
1
Maaf, tetapi ini tidak menjawab pertanyaan.
DerMike