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

163

У нас были некоторые дебаты на этой неделе в моей компании относительно того, как мы должны писать наши SQL-скрипты.

Фон: Наша база данных - Oracle 10g (до 11 скоро). Наша команда DBA использует SQLPlus для развертывания наших сценариев для производства.

Теперь у нас недавно было развертывание, потому что оно использовало как точку с запятой, так и косую черту (/). Точка с запятой была в конце каждого утверждения, а слэш - между операторами.

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

В script были добавлены триггеры, некоторые созданные представления, а также некоторые хранимые процедуры. Наличие как ;, так и / приводило к тому, что каждый оператор запускался дважды, вызывая ошибки (особенно на вставках, которые должны были быть уникальными).

В SQL Developer этого не происходит, в TOAD этого не происходит. Если вы выполняете определенные команды, они не будут работать без / в них.

В PL/SQL, если у вас есть подпрограмма (DECLARE, BEGIN, END), точка с запятой будет считаться частью подпрограммы, поэтому вам нужно использовать косую черту.

Итак, мой вопрос таков: если ваша база данных - это Oracle, каков правильный способ написать SQL script? Поскольку вы знаете, что ваша БД является Oracle, вы должны всегда использовать /?

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

6 ответов

30
Лучший ответ

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

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

273

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

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

; завершает инструкцию SQL, тогда как / выполняет все, что находится в текущем "буфере". Поэтому, когда вы используете ; и 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 script, как это:

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.

  • 1
    @amis, я новичок в Oracle и столкнулся с той же проблемой. Этот вопрос очень полезен, но во всех ответах дано объяснение «почему», а не «лучший способ» или какой-то способ обойти это. Итак, если я правильно понял, нет способа иметь только один сценарий и использовать его для всех инструментов ... или вы нашли какой-то способ?
  • 3
    @ceinmart: «лучший способ» - определить один (и только один) инструмент для выполнения сценариев SQL - и «правильность» сценария проверяется с помощью этого инструмента. Аналогично наличию одного компилятора для вашего языка программирования или одной конкретной версии среды выполнения (Java 7, .Net 4.0, PHP 5.x, ...)
Показать ещё 2 комментария
70

Я хотел прояснить некоторое использование между ; и /

В SQLPLUS:

  • ; означает "завершение текущего оператора, его выполнение и сохранение в буфер SQLPLUS"
  • <newline> после D.M.L. (SELECT, UPDATE, INSERT,...) или некоторые типы операторов DDL (создание таблиц и представлений) (которые не содержат ;), это означает, что хранить инструкцию в буфере, но не запускать ее.
  • / после ввода инструкции в буфер (с пробелом <newline>) означает "запустить в буфере D.M.L. или D.D.L. или PL/SQL.
  • RUN или R - это команда sqlsplus для отображения/вывода SQL в буфер и запускать ее. Он не завершит выражение SQL.
  • / во время ввода D.M.L. или D.D.L. или PL/SQL означает "завершение текущего оператора, его выполнение и сохранение в буфер SQLPLUS"

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

END;
/
  • 0
    Самый полезный ответ на вопрос, спасибо
23

Почти все развертывания 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>)
12

По моему мнению, все инструкции SQL не нуждаются в косой черте, поскольку они будут выполняться автоматически в конце точек с запятой, включая DDL, DML, DCL и TCL.

Для других блоков PL/SQL, включая процедуры, функции, пакеты и триггеры, поскольку они представляют собой несколько линейных программ, Oracle необходимо знать, когда нужно запускать блок, поэтому нам нужно написать косую черту в конце каждый блок позволяет Oracle запускать его.

1

Я использую только одну косую черту в конце каждого script, чтобы сказать sqlplus, что больше строк кода не существует. В середине script я не использую косую черту.

  • 0
    Так вы заказываете вещи, которые требуют / (например, подпрограммы и триггеры) в конце? Что делать, если у вас есть несколько триггеров? Я выполнил тест, и только первый из них выполняется, если между каждым из них нет /. Я что-то пропустил?
  • 0
    Я стараюсь избегать этого (если возможно), но если я не могу (как в триггерах), я использую точки с запятой и косые черты точно так же, как они используются в официальных скриптах, которые генерируют образцы схем oracle: download.oracle.com/docs /cd/B19306_01/server.102/b14198/… Для проблемы вставки я пытаюсь отделить сценарии, которые создают объекты, от тех, кто заполняет таблицы.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню