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

На этой неделе в моей компании проходили дебаты о том, как нам писать наши сценарии 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, следует всегда использовать /?

9 ответов

Решение

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

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

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

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

; завершает оператор 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 заявление.

Я хотел бы уточнить еще немного использования между ; и /

В 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;
/

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

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

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

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

используйте точку с запятой в файлах сценариев sql для разделения операторов sql, которые сообщают клиентскому программному обеспечению (SQL*Plus, SQL Developer), какие отдельные операторы необходимо выполнить.

используйте косую черту в файлах сценариев sql для разделения блоков pl /sql, которые сообщают клиентскому программному обеспечению (SQL*Plus, SQL Developer), какие отдельные блоки pl /sql должны выполняться.

используйте косую черту в командной строке SQL*Plus, если вы хотите выполнить буферизованный оператор (да, это один оператор sql без точки с запятой или блок pl /sql без косой черты).

Используйте косую черту после операторов, которые заканчиваются на «end;», в противном случае не используйте ее.

Перед созданием типа объекта в Oracle создаются фиктивные типы для ссылки на другие типы, которые еще не определены. Косая черта используется для выполнения самых последних изменений определения типа или для замены существующего типа в буфере SQL замененным типом.

Ссылки:https://docs.oracle.com/cd/E18283_01/server.112/e16604/ch_twelve004.htm

Другие вопросы по тегам