Когда мне нужно использовать точку с запятой против косой черты в Oracle SQL?

179

На этой неделе в моей компании велись споры о том, как нам писать наши сценарии SQL.

История вопроса: наша база данных - Oracle 10g (скоро обновится до 11). Наша команда администраторов баз данных использует 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, следует ли вам всегда использовать /?

amischiefr
источник
1
В случае, если кто-то выполняет экспорт базы данных с помощью SQLDeveloper, существует флажок «Терминатор», который при выборе использует точки с запятой для завершения каждого оператора. Эта опция выбрана по умолчанию. Снимите флажок, чтобы удалить точки с запятой и избежать дублирования операторов
Руслан Уралов
7
Я просто упомяну, что в языке SQL нет точки с запятой. Это просто символ-терминатор по умолчанию в SQL * Plus (вы можете установить sqlterminatorего, !если хотите), и этому соглашению обычно следуют другие инструменты. Однако язык PL / SQL использует точки с запятой в качестве обязательного элемента синтаксиса.
Уильям Робертсон

Ответы:

31

Это вопрос предпочтений, но я предпочитаю видеть сценарии, которые последовательно используют косую черту - таким образом все «единицы» работы (создание объекта PL / SQL, запуск анонимного блока PL / SQL и выполнение оператора DML) могут быть выбрано легче на глаз.

Кроме того, если вы в конечном итоге перейдете к развертыванию, например Ant, это упростит определение целей, чтобы иметь согласованный разделитель операторов.

dpbradley
источник
1
этот ответ не объясняет почему /или не ;видит ответ @a_horse_with_no_name или @Mr_Moneybags для большего контекста
Кей
333

Я знаю, что это старая ветка, но я наткнулся на нее и чувствую, что это не объяснено полностью.

В SQL * Plus существует огромная разница между значениями a /и a, ;потому что они работают по-разному.

В ;Завершает SQL заявление, в то время как /выполняет все , что находится в текущем «буфер». Поэтому, когда вы используете a ; и a, /оператор фактически выполняется дважды.

Вы можете легко увидеть это с помощью оператора /после выполнения:

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оператор.

a_horse_with_no_name
источник
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»

ПРИМЕЧАНИЕ. Поскольку ;для PL / SQL используется завершение оператора ;, SQLPLUS не может означать «завершить текущий оператор, выполнить его и сохранить в буфере SQLPLUS», поскольку мы хотим, чтобы весь блок PL / SQL был полностью в буфер, затем выполните его. Блоки PL / SQL должны заканчиваться:

END;
/
Mr_Moneybags
источник
22

Почти все развертывания Oracle выполняются через SQL * Plus (это странное маленькое средство командной строки, которое использует ваш администратор баз данных). А в 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>)
JVA
источник
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