Oracle SQL'de noktalı virgül ve eğik çizgi ne zaman kullanmam gerekir?


179

SQL scriptlerimizi nasıl yazmamız gerektiği konusunda şirketimde bu hafta biraz tartıştık.

Arka plan: Veritabanımız Oracle 10g (yakında 11'e yükseltiliyor). DBA ekibimiz, komut dosyalarımızı üretime dağıtmak için SQLPlus kullanıyor.

Şimdi, son zamanlarda başarısız olan bir konuşlandırma gerçekleştirdik çünkü noktalı virgül ve eğik çizgi ( /) kullandı. Noktalı virgül her ifadenin sonunda ve eğik çizgi ifadeler arasındaydı.

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

Kodda daha sonra eklenen bazı tetikleyiciler, bazı görünümler ve bazı saklı yordamlar vardı. Hem ;ve hem de /her ifadenin iki kez çalışmasına neden olan hatalara (özellikle benzersiz olması gereken eklerde) neden olur.

SQL Developer'da bu gerçekleşmez, TOAD'da bu olmaz. Belirli komutları çalıştırırsanız, bunlar olmadan kullanılmazlar /.

PL / SQL'de bir alt programınız varsa (DECLARE, BEGIN, END) kullanılan noktalı virgül, alt programın bir parçası olarak kabul edilir, bu nedenle eğik çizgiyi kullanmanız gerekir.

Benim sorum şu: Eğer veritabanınız Oracle ise, SQL betiğinizi yazmanın doğru yolu nedir? DB'nizin Oracle olduğunu bildiğiniz için her zaman /?


1
Birisi SQLDeveloper ile bir veritabanı ihracat yapıyorsa, seçildiğinde her deyimi sonlandırmak için noktalı virgül kullanan "Terminatör" adlı bir onay kutusu vardır. Bu seçim varsayılan olarak seçilmiş. Noktalı virgülleri kaldırmak ve yinelenen deyim yürütmesini önlemek için seçimi kaldırın
Ruslans Uralovs

7
Sadece bu eski iş parçacığını ölüme sokmak için SQL dilinin noktalı virgül olmadığını söyleyeceğim. Bu sadece bir SQL * Plus varsayılan sonlandırıcı karakteri (Belirleyebileceğiniz olduğu sqlterminatoriçin !eğer isterseniz) ve bu kongre diğer araçlar tarafından takip edilecek eğilimindedir. Ancak PL / SQL dili, noktalı virgülleri zorunlu bir sözdizimi öğesi olarak kullanır.
William Robertson

Yanıtlar:


31

Bu bir tercih meselesidir, ancak eğik çizgiyi sürekli olarak kullanan komut dosyalarını görmeyi tercih ederim - bu şekilde işin tüm "birimleri" (bir PL / SQL nesnesi oluşturma, bir PL / SQL anonim bloğu çalıştırma ve bir DML ifadesi çalıştırma) gözle daha kolay seçildi.

Ayrıca, sonunda dağıtım için Ant gibi bir şeye geçerseniz, tutarlı bir deyim sınırlayıcıya sahip olmak için hedeflerin tanımını basitleştirecektir.


1
Bu cevap neden açıklamıyor /veya ;daha fazla bağlam için @a_horse_with_no_name veya @Mr_Moneybags cevabını bakınız
Kay

333

Bu eski bir iplik olduğunu biliyorum, ama ben sadece tökezledi ve bu tamamen açıklanmadı hissediyorum.

SQL * Plus'ta a /ve a'nın anlamları arasında büyük bir fark vardır ;çünkü farklı çalışırlar.

;Uçları bir SQL deyimi, oysa /akım ne varsa yürütür "tampon". Yani a ; ve a /kullandığınızda ifade aslında iki kez yürütülür.

/Bir deyimi çalıştırdıktan sonra kullanarak bunu kolayca görebilirsiniz :

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

Bu durumda aslında hata fark edilir.


Ancak böyle bir SQL komut dosyası olduğunu varsayarsak:

drop table foo;
/

Ve bu SQL * Plus içinden çalıştırılırsa, bu çok kafa karıştırıcı olacaktır:

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

Esas olarak /, ;bir CREATE PROCEDUREifade gibi gömülü ifadeleri çalıştırmak için gereklidir .


2
@amis, Oracle için yeniyim ve aynı problemle karşılaşıyorum. Bu soru çok faydalıdır, ancak tüm cevaplar "neden" değil "çalışmanın" en iyi yolu "ya da bu sorunu çözmenin bir yolu hakkında bir açıklama yaptı. Yani, doğru anladıysam, tek bir senaryoya sahip olmanın ve tüm araçlar için kullanılabilir kalmasının bir yolu yoktur ... yoksa bir şekilde keşfediyor musunuz?
ceinmart

5
@ ceinmart: "en iyi yol" SQL komut dosyalarını çalıştırmak için bir (ve yalnızca bir) araç tanımlamaktır - ve bir komut dosyasının "doğruluğu" bu araç kullanılarak doğrulanır. Programlama diliniz için bir derleyiciye veya çalışma zamanı ortamınızın belirli bir sürümüne (Java 7, .Net 4.0, PHP 5.x, ...) benzer
a_horse_with_no_name 21:13

1
İyi cevap. Sadece ben mi yoksa Oracle diğer DB'lere kıyasla aptal ve arkaik mi? Çok fazla Sybase kullandım ve çok daha sezgisel görünüyor.
splashout

1
@splashout: iyi, varsayılan ayırıcıyı ( ;) içeren ifadeleri çalıştırmak istiyorsanız, alternatif bir ayırıcı belirtmek için bir yol bulmanız gerekir
a_horse_with_no_name 10:08

97

Ve arasındaki bazı kullanımları açıklığa kavuşturmak istedim ;./

SQLPLUS'ta:

  1. ; "geçerli ifadeyi sonlandır, çalıştır ve SQLPLUS arabelleğine kaydet"
  2. <newline>DML (SELECT, UPDATE, INSERT, ...) ifadesinden veya DDL (Tablolar ve Görünümler Oluşturma) ifadelerinden (hayır içeren ;) bazı ifadelerden sonra, ifadeyi arabelleğe kaydetme, ancak çalıştırmama anlamına gelir.
  3. /tampon içine bir ifade girdikten sonra (boş <newline>) " tamponda DML veya DDL veya PL / SQL çalıştır" anlamına gelir.
  4. RUNveya RSQL'de arabellekteki SQL gösterimini / çıktısını almak ve çalıştırmak için bir sqlsplus komutudur. SQL deyimini sonlandırmaz.
  5. / DML veya DDL veya PL / SQL girilmesi sırasında "geçerli ifadeyi sonlandır, çalıştır ve SQLPLUS arabelleğine kaydet"

NOT: Çünkü ;bir bildiri bitirmek için PL / SQL için kullanılmaktadır ;biz bütün PL / SQL bloğu tamamen olmak istiyorum, çünkü demek "Mevcut deyimi sonlandırmak, onu yürütmek ve SQLplus tampon alanına kaydetmek" için SQLPlus tarafından kullanılamaz arabellek, sonra yürütmek. PL / SQL blokları aşağıdakilerle bitmelidir:

END;
/

22

Hemen hemen tüm Oracle dağıtımları SQL * Plus (DBA'nızın kullandığı garip küçük komut satırı aracı) aracılığıyla yapılır. Ve SQL * Plus'ta yalnız bir eğik çizgi temelde "az önce yürüttüğüm son SQL veya PL / SQL komutunu yeniden çalıştır" anlamına gelir.

Görmek

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

Temel kural, yaptığınız BEGIN .. ENDveya kullanabileceğiniz şeylerle eğik çizgi kullanmak olacaktır CREATE OR REPLACE.

Benzersiz kullanımı gereken kesici uçlar için

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

Anladığım kadarıyla, tüm SQL ifadelerinin DDL, DML, DCL ve TCL ifadeleri de dahil olmak üzere noktalı virgüllerin sonunda otomatik olarak çalışacağı için eğik çizgiye gerek yoktur.

Yordamlar, İşlevler, Paketler ve Tetikleyiciler dahil olmak üzere diğer PL / SQL blokları için, bunlar çok satırlı programlar olduklarından, Oracle'ın bloğu ne zaman çalıştıracağını bilmek için bir yola ihtiyacı vardır, bu nedenle her bloğun sonuna bir eğik çizgi yazmamız gerekir izin Oracle onu çalıştırın.


1

Ben sqlplus daha fazla kod satırı olmadığını söylemek için, her komut dosyasının sonunda bir kez eğik çizgi kullanın. Senaryonun ortasında, eğik çizgi kullanmıyorum.


Sonunda / (alt programlar ve tetikleyiciler gibi) gerektiren şeyleri sipariş ediyor musunuz? Birden fazla tetikleyiciniz varsa ne olur? Bir test yaptım ve her biri bir / arasında olmadığı sürece sadece ilkini yürütür. Bir şey mi kaçırıyorum?
amischiefr

Bundan kaçınmaya çalışıyorum (mümkünse), ancak yapamazsam (tetikleyicilerde olduğu gibi), noktalı virgülleri ve eğik çizgileri tam olarak oracle örnek şemalarını oluşturan resmi komut dosyalarında kullandığım gibi kullanıyorum: download.oracle.com/docs /cd/B19306_01/server.102/b14198/… Ekleme sorunu için, nesneleri oluşturan komut dosyalarını tabloları dolduranlardan ayırmaya çalışıyorum.
Jonathan

1
Üzgünüm, ama bu soruya cevap vermiyor.
DerMike
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.