Когда мне нужно использовать точку с запятой вместо косой черты в 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, следует ли всегда использовать /?


person amischiefr    schedule 03.07.2009    source источник
comment
Если кто-то выполняет экспорт базы данных с помощью SQLDeveloper, есть флажок Терминатор, который при выборе использует точку с запятой для завершения каждого оператора. Этот вариант выбран по умолчанию. Снимите флажок, чтобы удалить точку с запятой и избежать дублирования выполнения оператора   -  person Ruslans Uralovs    schedule 04.01.2012
comment
Просто чтобы бессмысленно забить эту старую ветку до смерти, я упомяну, что в языке SQL нет точки с запятой. Это просто символ-терминатор по умолчанию в SQL * Plus (вы можете установить sqlterminator на !, если хотите), и этому соглашению, как правило, следуют другие инструменты. Однако в языке PL / SQL точки с запятой используются в качестве обязательного элемента синтаксиса.   -  person William Robertson    schedule 02.06.2016
comment
@WilliamRobertson Вы должны добавить свой комментарий в качестве ответа, поскольку эта информация отсутствует в ответах.   -  person Roland    schedule 06.02.2021


Ответы (7)


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

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

person dpbradley    schedule 03.07.2009
comment
этот ответ не объясняет, почему / или ; см. ответ @a_horse_with_no_name или @Mr_Moneybags для получения дополнительной информации - person Kay; 06.04.2020

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

В 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:

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.

person a_horse_with_no_name    schedule 18.04.2012
comment
@amis, я новичок в Oracle и столкнулся с той же проблемой. Этот вопрос очень полезен, но во всех ответах объясняется, почему не лучший способ работы или какой-то способ обойти это. Итак, если я правильно понял, невозможно создать только один скрипт и сохранить его пригодным для всех инструментов ... или вы что-нибудь обнаружите? - person ceinmart; 21.11.2013
comment
@ceinmart: лучший способ - определить один (и только один) инструмент для выполнения сценариев SQL - и правильность сценария проверяется с помощью этого инструмента. Подобно одному компилятору для вашего языка программирования или одной конкретной версии вашей среды выполнения (Java 7, .Net 4.0, PHP 5.x, ...) - person a_horse_with_no_name; 21.11.2013
comment
Хороший ответ. Это только у меня, или Oracle тупой и архаичный по сравнению с другими БД? Я много использовал Sybase, и это кажется более интуитивным. - person splashout; 10.04.2018
comment
@splashout: ну, если вы хотите запускать операторы, содержащие разделитель по умолчанию (;), вам нужно найти способ указать альтернативный разделитель - person a_horse_with_no_name; 10.04.2018

Я хотел уточнить, как еще можно использовать ; и /

В SQLPLUS:

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

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

END;
/
person Mr_Moneybags    schedule 15.01.2014
comment
Вы сказали, что ; нельзя использовать для обозначения пункта (1), когда дело доходит до PL / SQL, но почему END; недостаточно для обозначения завершения? Разве это не однозначно? - person ForgottenUmbrella; 09.05.2021

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

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

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

person Jerry    schedule 26.06.2012

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

person Jonathan    schedule 03.07.2009
comment
Так вы заказываете вещи, которые требуют / (например, подпрограммы и триггеры) в конце? Что делать, если у вас несколько триггеров? Я запустил тест, и выполняется только первый, если между каждым из них нет /. Я что-то упускаю? - person amischiefr; 03.07.2009
comment
Я стараюсь избегать этого (если возможно), но если не могу (например, в триггерах), я использую точки с запятой и косую черту точно так же, как они используются в официальных скриптах, которые генерируют схемы образцов oracle: download.oracle.com/docs/cd/B19306_01/server.102/b14198 / Что касается проблемы вставки, я стараюсь отделить сценарии, создающие объекты, от сценариев, заполняющих таблицы. - person Jonathan; 03.07.2009
comment
Извините, но это не ответ на вопрос. - person DerMike; 02.06.2017

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

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

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

person Kamal SABBAR    schedule 25.03.2021