ฉันต้องใช้เซมิโคลอนกับสแลชใน Oracle SQL เมื่อใด


179

เราได้มีการถกเถียงกันในสัปดาห์นี้ที่ บริษัท ของฉันว่าเราควรเขียนสคริปต์ SQL ของเราอย่างไร

พื้นหลัง: ฐานข้อมูลของเราคือ Oracle 10g (อัปเกรดเป็น 11 เร็ว ๆ นี้) ทีม DBA ของเราใช้ SQLPlus เพื่อปรับใช้สคริปต์ของเราเพื่อการผลิต

ตอนนี้เรามีการปรับใช้ที่ล้มเหลวเมื่อเร็ว ๆ นี้เพราะมันใช้ทั้งอัฒภาคและฟอร์เวิร์ดสแลช ( /) อัฒภาคอยู่ที่ท้ายของแต่ละคำสั่งและเครื่องหมายทับอยู่ระหว่างข้อความ

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

มีทริกเกอร์บางอย่างถูกเพิ่มเข้ามาในสคริปต์บางมุมมองที่สร้างขึ้นรวมถึงบางกระบวนงานที่เก็บไว้ การมีทั้ง;และ/ทำให้แต่ละคำสั่งรันสองครั้งทำให้เกิดข้อผิดพลาด (โดยเฉพาะในส่วนแทรกซึ่งจำเป็นต้องไม่ซ้ำกัน)

ใน SQL Developer สิ่งนี้จะไม่เกิดขึ้นใน TOAD สิ่งนี้จะไม่เกิดขึ้น หากคุณเรียกใช้คำสั่งบางอย่างพวกเขาจะไม่ทำงานหากไม่มีคำสั่ง/เหล่านั้น

ใน PL / SQL หากคุณมีโปรแกรมย่อย (DECLARE, BEGIN, END) เครื่องหมายอัฒภาคที่ใช้จะถูกพิจารณาว่าเป็นส่วนหนึ่งของโปรแกรมย่อยดังนั้นคุณต้องใช้เครื่องหมายทับ

ดังนั้นคำถามของฉันคือ: ถ้าฐานข้อมูลของคุณคือ Oracle, วิธีที่เหมาะสมในการเขียนสคริปต์ SQL ของคุณคืออะไร? เมื่อคุณรู้ว่าฐานข้อมูลของคุณเป็น Oracle คุณควรใช้/หรือไม่


1
ในกรณีที่มีคนทำการส่งออกฐานข้อมูลกับ SQLDeveloper จะมีช่องทำเครื่องหมายที่เรียกว่า "Terminator" ซึ่งเมื่อเลือกจะใช้เครื่องหมายอัฒภาคเพื่อยุติแต่ละคำสั่ง ตัวเลือกนี้จะถูกเลือกโดยค่าเริ่มต้น ยกเลิกการเลือกเพื่อลบเครื่องหมายอัฒภาคและเพื่อหลีกเลี่ยงการดำเนินการคำสั่งซ้ำ
Ruslans Uralovs

7
เพียงแค่โบยบินด้ายเก่าไปสู่ความตายอย่างไร้จุดหมายฉันจะพูดถึงว่าภาษา SQL นั้นไม่มีเครื่องหมายอัฒภาค มันเป็นเพียงตัวละครที่เทอร์มิเริ่มต้นใน SQL * Plus (คุณสามารถตั้งค่าsqlterminatorการ!หากคุณต้องการ) และการประชุมนี้มีแนวโน้มที่จะตามมาด้วยเครื่องมืออื่น ๆ อย่างไรก็ตามภาษา PL / SQL ใช้เครื่องหมายอัฒภาคเป็นองค์ประกอบไวยากรณ์บังคับ
William Robertson

คำตอบ:


31

มันเป็นเรื่องของความพึงพอใจ แต่ฉันชอบที่จะเห็นสคริปต์ที่ใช้สแลชอย่างสม่ำเสมอ - ด้วยวิธีนี้ "หน่วย" ทั้งหมดของการทำงาน (การสร้างวัตถุ PL / SQL, การรันบล็อกที่ไม่ระบุชื่อ PL / SQL และดำเนินการคำสั่ง DML) หยิบออกมาได้ง่ายขึ้นด้วยตา

นอกจากนี้หากในที่สุดคุณย้ายไปที่สิ่งที่ต้องการ Ant สำหรับการปรับใช้มันจะทำให้คำจำกัดความของเป้าหมายง่ายขึ้นเพื่อให้มีตัวคั่นคำสั่งที่สอดคล้องกัน


1
คำตอบนี้ไม่ได้อธิบายว่าทำไม/หรือ;ดูคำตอบของ @a_horse_with_no_name หรือ @Mr_Moneybags สำหรับบริบทเพิ่มเติม
Kay

333

ฉันรู้ว่านี่เป็นด้ายเก่า แต่ฉันเพิ่งสะดุดกับมันและฉันรู้สึกว่าสิ่งนี้ยังไม่ได้รับการอธิบายอย่างสมบูรณ์

มีความแตกต่างอย่างมากใน SQL * Plus ระหว่างความหมายของ a /และ a ;เพราะมันทำงานต่างกัน

;ปลายคำสั่ง SQL ในขณะที่/รันสิ่งที่อยู่ในปัจจุบัน "กันชน" ดังนั้นเมื่อคุณใช้ a ; และ a /คำสั่งจะถูกดำเนินการสองครั้งจริง ๆ

คุณสามารถเห็นได้อย่างง่ายดายว่าการ/ใช้คำสั่ง after after

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

ในกรณีนี้มีใครสังเกตเห็นข้อผิดพลาดจริง


แต่สมมติว่ามีสคริปต์ SQL ดังนี้:

drop table foo;
/

และสิ่งนี้ถูกเรียกใช้จากภายใน SQL * Plus ดังนั้นสิ่งนี้จะทำให้เกิดความสับสนมาก:

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

/ต้องใช้หลักในการที่จะเรียกใช้งบที่มีการฝังตัว;เช่นCREATE PROCEDUREคำสั่ง


2
@amis ฉันใหม่กับ Oracle และได้รับปัญหาเดียวกัน คำถามนี้มีประโยชน์มาก แต่คำตอบทั้งหมดให้คำอธิบายเกี่ยวกับ "ทำไม" ไม่ใช่ "วิธีที่ดีที่สุด" ในการทำงานหรือวิธีแก้ไขปัญหานี้ ดังนั้นถ้าฉันเข้าใจถูกต้องไม่มีวิธีที่จะมีเพียงสคริปต์เดียวและทำให้มันใช้งานได้สำหรับเครื่องมือทั้งหมด ... หรือคุณค้นพบบางวิธี?
ceinmart

5
@ceinmart: "วิธีที่ดีที่สุด" คือการกำหนดเครื่องมือหนึ่ง (และเพียงหนึ่ง) เพื่อรันสคริปต์ SQL - และ "ความถูกต้อง" ของสคริปต์นั้นได้รับการตรวจสอบโดยใช้เครื่องมือนั้น คล้ายกับการมีหนึ่งคอมไพเลอร์สำหรับภาษาการเขียนโปรแกรมของคุณหรือเวอร์ชันเฉพาะของสภาพแวดล้อมรันไทม์ของคุณ (Java 7, .Net 4.0, PHP 5.x, ... )
a_horse_with_no_name

1
คำตอบที่ดี. มันเป็นเพียงฉันหรือเป็น Oracle โง่และคร่ำคร่าเมื่อเทียบกับฐานข้อมูลอื่น ๆ ? ฉันใช้ Sybase มากและดูเหมือนว่าจะใช้งานง่ายกว่ามาก
splashout

1
@splashout: ดีถ้าคุณต้องการเรียกใช้คำสั่งที่มีตัวคั่นเริ่มต้น ( ;) แล้วคุณต้องหาวิธีในการระบุตัวคั่นทางเลือก
a_horse_with_no_name

97

ฉันต้องการชี้แจงเพิ่มเติมการใช้ระหว่าง;และ/

ใน SQLPLUS:

  1. ; หมายถึง "ยุติคำสั่งปัจจุบันดำเนินการและเก็บไว้ในบัฟเฟอร์ SQLPLUS"
  2. <newline>หลังคำสั่ง DML (SELECT, UPDATE, INSERT, ... ) หรือคำสั่ง DDL (การสร้างตารางและมุมมอง) บางประเภท (ที่ไม่มี;) หมายถึงเก็บคำสั่งลงในบัฟเฟอร์ แต่ไม่เรียกใช้
  3. /หลังจากป้อนคำสั่งลงในบัฟเฟอร์ (พร้อมช่องว่าง<newline>) หมายถึง "เรียกใช้ DML หรือ DDL หรือ PL / SQL ในบัฟเฟอร์
  4. RUNหรือRเป็นคำสั่ง sqlsplus เพื่อแสดง / ส่งออก SQL ในบัฟเฟอร์และเรียกใช้ มันจะไม่ยุติคำสั่ง SQL
  5. / ระหว่างการป้อน DML หรือ DDL หรือ PL / SQL หมายถึง "ยุติคำสั่งปัจจุบันเรียกใช้และเก็บไว้ในบัฟเฟอร์ SQLPLUS"

หมายเหตุ:เนื่องจาก;ใช้สำหรับ PL / SQL เพื่อจบคำสั่ง;ไม่สามารถใช้โดย SQLPLUS เพื่อหมายถึง "ยุติคำสั่งปัจจุบันดำเนินการและเก็บไว้ในบัฟเฟอร์ SQLPLUS" เพราะเราต้องการให้ทั้ง PL / SQL บล็อกทั้งหมดอยู่ใน บัฟเฟอร์จากนั้นดำเนินการ บล็อก PL / SQL จะต้องลงท้ายด้วย:

END;
/

22

การปรับใช้ Oracle เกือบทั้งหมดทำได้ผ่าน SQL * Plus (เครื่องมือบรรทัดคำสั่งเล็ก ๆ แปลก ๆ ที่ DBA ของคุณใช้) และใน SQL * Plus เครื่องหมายสแลชเดียวหมายความว่า "เรียกใช้งานคำสั่ง SQL หรือ PL / SQL ล่าสุดที่ฉันเพิ่งเรียกใช้งานอีกครั้ง"

ดู

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

กฎของหัวแม่มือคือการใช้สแลชกับสิ่งที่ทำBEGIN .. ENDหรือที่ที่คุณสามารถCREATE OR REPLACEใช้ได้

สำหรับเม็ดมีดที่ต้องใช้งานซ้ำกัน

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

จากความเข้าใจของฉันคำสั่ง SQL ทั้งหมดไม่จำเป็นต้องใช้สแลชเพราะจะรันโดยอัตโนมัติเมื่อสิ้นสุดเซมิโคลอนรวมถึงคำสั่ง DDL, DML, DCL และ TCL

สำหรับบล็อก PL / SQL อื่น ๆ รวมถึงขั้นตอน, ฟังก์ชั่น, แพคเกจและทริกเกอร์เนื่องจากเป็นโปรแกรมหลายบรรทัด Oracle ต้องการวิธีทราบว่าเมื่อใดที่จะเรียกใช้บล็อกดังนั้นเราจึงต้องเขียนเครื่องหมายสแลชที่ส่วนท้ายของแต่ละบล็อก ปล่อยให้ Oracle รัน


1

ฉันใช้เครื่องหมายทับซ้ายหนึ่งครั้งในตอนท้ายของแต่ละสคริปต์เพื่อบอก sqlplus ว่าไม่มีบรรทัดของโค้ดมากกว่านี้ ในช่วงกลางของสคริปต์ฉันไม่ได้ใช้เครื่องหมายทับ


คุณจะสั่งสิ่งที่ต้องการ / (เช่นโปรแกรมย่อยและทริกเกอร์) ในตอนท้ายหรือไม่ ถ้าคุณมีทริกเกอร์หลายตัวล่ะ ฉันทำการทดสอบและมีเพียงการทดสอบแรกที่เรียกใช้เว้นแต่จะมี / ระหว่างแต่ละรายการ ฉันพลาดอะไรไปรึเปล่า?
amischiefr

ฉันพยายามหลีกเลี่ยง (ถ้าเป็นไปได้) แต่ถ้าฉันไม่สามารถ (เหมือนในทริกเกอร์) ฉันใช้เครื่องหมายอัฒภาคและเครื่องหมายสแลชตรงตามที่ใช้ในสคริปต์อย่างเป็นทางการที่สร้าง schema ตัวอย่างของ oracle: download.oracle.com/docs /cd/B19306_01/server.102/b14198/ … สำหรับปัญหาการแทรกฉันพยายามที่จะแยกสคริปต์ที่สร้างวัตถุจากผู้ที่เติมตาราง
309 Jonathan ใน

1
ขออภัย แต่นี่ไม่ได้ตอบคำถาม
DerMike
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.