Коли мені потрібно використовувати крапку з комою та косою косою в 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, є прапорець під назвою "Термінатор", який при виборі використовує крапки з комою для завершення кожного оператора. Цей параметр вибрано за замовчуванням. Скасуйте вибір, щоб видалити крапки з комою та уникнути повторного виконання заяв
Ruslans Uralovs

7
Тільки для того, щоб безглуздо забити цю стару нитку до смерті, я зазначу, що мова SQL не має крапки з комою. Це просто символ термінатора за замовчуванням в SQL * Plus (ви можете встановити , sqlterminatorщоб , !якщо ви хочете) , і ця угода , як правило, йдуть інші інструменти. Однак мова PL / SQL використовує крапки з комою як обов'язковий елемент синтаксису.
Вільям Робертсон

Відповіді:


31

Це питання переваги, але я вважаю за краще бачити сценарії, які послідовно використовують косу рису - таким чином всі "одиниці" роботи (створення об'єкта PL / SQL, запуск анонімного блоку PL / SQL та виконання оператора DML) можуть бути вибирається легше на очі.

Крім того, якщо ви врешті-решт перейдете до чогось на зразок Ant для розгортання, це спростить визначення цілей, щоб мати послідовний роздільник обмежень.


1
ця відповідь не пояснює , чому /або ;побачити відповідь @a_horse_with_no_name або @Mr_Moneybags для більш контексту
Кей

333

Я знаю, що це стара нитка, але я просто натрапив на неї і відчуваю, що це не було пояснено повністю.

Існує величезна різниця в SQL * Plus між значеннями a /і a, ;оскільки вони працюють по-різному.

У ;Завершує SQL заяву, в той час як /виконує всі , що знаходиться в поточному «буфер». Тому , коли ви використовуєте ; і/ заява фактично виконується двічі.

Ви можете легко побачити, що за /допомогою оператора після запуску:

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 і, здається, набагато інтуїтивніше.
плескіт

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"

ПРИМІТКА. Оскільки 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

Я намагаюся уникати цього (якщо можливо), але якщо я не можу (як у тригерах), я використовую крапки з комою та косою рисою точно так, як це використовується в офіційних сценаріях, що генерують схеми зразків Oracle: download.oracle.com/docs /cd/B19306_01/server.102/b14198/… Для проблеми із вставками я намагаюся відокремити сценарії, які створюють об'єкти, від тих, хто заповнює таблиці.
Джонатан

1
Вибачте, але це не відповідає на питання.
DerMike
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.