DROP ... СОЗДАТЬ против ALTER - PullRequest
       59

DROP ... СОЗДАТЬ против ALTER

52 голосов
/ 29 октября 2009

Когда дело доходит до создания хранимых процедур, представлений, функций и т. Д., Лучше ли выполнять DROP ... CREATE или ALTER для объекта?

Я видел множество «стандартных» документов, в которых говорится, что нужно делать DROP ... CREATE, но я видел множество комментариев и аргументов в пользу метода ALTER.

Метод ALTER сохраняет безопасность, хотя я слышал, что метод DROP ... CREATE вызывает перекомпиляцию всего SP при первом запуске вместо просто перекомпиляции на уровне операторов.

Может кто-нибудь сказать мне, есть ли другие преимущества / недостатки использования одного над другим?

Ответы [ 12 ]

52 голосов
/ 29 октября 2009

Вот как мы это делаем:

if object_id('YourSP') is null
    exec ('create procedure dbo.YourSP as select 1')
go
alter procedure dbo.YourSP
as
...

Код создает хранимую процедуру "заглушки", если она еще не существует, в противном случае он выполняет изменение. Таким образом, любые существующие разрешения для процедуры сохраняются, даже если вы выполняете сценарий повторно.

47 голосов
/ 29 октября 2009

ALTER также принудительно перекомпилирует всю процедуру. Перекомпиляция уровня оператора применяется к инструкциям внутри процедур, например. один SELECT, который перекомпилируется из-за изменений базовых таблиц, без каких-либо изменений в процедуре. Даже было бы невозможно выборочно перекомпилировать только определенные операторы процедуры ALTER, чтобы понять что изменилось в тексте SQL после процедуры ALTER, которую сервер должен был бы ... скомпилировать.

Для всех объектов ALTER всегда лучше, потому что он сохраняет всю безопасность, все расширенные свойства, все зависимости и все ограничения.

8 голосов
/ 29 октября 2009

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

3 голосов
/ 17 ноября 2017

Начиная с SQL Server 2016 с пакетом обновления 1 (SP1), теперь у вас есть возможность использовать синтаксис CREATE OR ALTER для хранимых процедур, функций, триггеров и представлений. См. CREATE OR ALTER - еще одно замечательное улучшение языка в SQL Server 2016 с пакетом обновления 1 в блоге компонента SQL Server Database Engine. Например:

CREATE OR ALTER PROCEDURE dbo.MyProc
AS
BEGIN
    SELECT * FROM dbo.MyTable
END;
1 голос
/ 14 ноября 2013

Я не знаю, можно ли сделать такой общий комментарий и сказать: «ALTER лучше». Я думаю, что все зависит от ситуации. Если вам требуется такой вид гранулярных разрешений вплоть до уровня процедуры, вам, вероятно, следует обработать это в отдельной процедуре. Есть преимущества того, чтобы бросить и воссоздать. Он очищает существующую безопасность и сбрасывает то, что предсказуемо.

Я всегда предпочитал использовать drop / пересоздать. Я также обнаружил, что их проще хранить в системе контроля версий. Вместо того, чтобы делать .... если существует, измените, а если не существует, создайте.

С учетом сказанного ... если ты знаешь, что делаешь ... Не думаю, что это имеет большое значение.

1 голос
/ 29 октября 2009

Если у вас есть функция / хранимый процесс, который, например, очень часто вызывается с веб-сайта, это может вызвать проблемы.

Сохраненный процесс будет отброшен на несколько миллисекунд / секунд, и в течение этого времени все запросы не будут выполнены.

Если вы делаете изменения, у вас нет этой проблемы.

Шаблоны для вновь созданного хранимого процесса обычно имеют такую ​​форму:

IF EXISTS (SELECT * FROM sysobjects WHERE type = 'P' AND name = '<name>')
    BEGIN
        DROP PROCEDURE <name>
    END
GO

CREATE PROCEDURE <name>
......

Однако лучше наоборот, imo:

Если сохраненный процесс / функция / и т. Д. Не существует, создайте его с помощью фиктивного оператора выбора. Тогда alter всегда будет работать - он никогда не будет сброшен.

Для этого у нас есть сохраненный процесс, поэтому наши хранимые процедуры / функции обычно выглядят так:

EXEC Utils.pAssureExistance 'Schema.pStoredProc'
GO

ALTER PROCECURE Schema.pStoredProc
...

и мы используем тот же хранимый процесс для функций:

EXEC Utils.pAssureExistance 'Schema.fFunction'
GO

ALTER FUNCTION Schema.fFunction
...

В Utils.pAssureExistance мы делаем IF и смотрим на первый символ после «.»: Если это «f», мы создаем фиктивную функцию, если это «p», мы создаем фиктивный хранимый процесс.

Будьте осторожны, если вы создаете фиктивную скалярную функцию и ваш ALTER использует табличную функцию, функция ALTER FUNCTION завершится ошибкой, сказав, что она не совместима.

Опять же, Utils.pAssureExistance может быть полезен с дополнительным необязательным параметром

EXEC Utils.pAssureExistance 'Schema.fFunction', 'TableValuedFunction'

создаст фиктивную табличную функцию,

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

Однако процедура alter будет ждать, пока все запросы прекратят использовать сохраненный процесс, и затем изменит его. Если запросы «блокируют» хранимый процесс слишком долго (скажем, пару секунд), ALTER перестанет ожидать блокировки и в любом случае изменит сохраненный процесс: в этот момент запросы, использующие хранимый процесс, вероятно, потерпят неудачу.

0 голосов
/ 20 июля 2018

Если вы выполняете DROP , а затем используете CREATE , у вас есть почти тот же эффект, что и при использовании оператора ALTER VIEW . Проблема заключается в том, что вам необходимо полностью восстановить свои разрешения на то, кто может и не может использовать представление. ALTER сохраняет любую информацию о зависимостях и устанавливает разрешения.

0 голосов
/ 22 марта 2015

Лучше добавить с пропуском, если существует, потому что, если у вас есть несколько сред, когда вы перемещаете скрипт в QA или тестируете, вы не знаете, существует ли скрипт в этой среде. При добавлении капли (если она уже существует) и последующем добавлении вы будете застрахованы независимо от того, существует она или нет. Затем вам необходимо повторно применить разрешения, но это лучше, чем прослушивание сценария установки с ошибкой.

0 голосов
/ 02 ноября 2009

Мы привыкли использовать alter, когда работали над разработкой, создавая новые функции или изменяя их. Когда мы закончили с нашей разработкой и тестированием, мы сделали бы каплю и создали. Это модифицирует метку даты / времени на процессорах, чтобы вы могли отсортировать их по дате / времени.

Это также позволило нам увидеть, что было разбито по дате для каждого отправляемого нами материала.

0 голосов
/ 29 октября 2009

DROP обычно теряет разрешения и любые расширенные свойства.

В некоторых пользовательских функциях ALTER также теряет расширенные свойства (определенно в многозначных табличных функциях SQL Server 2005).

Обычно я не делаю DROP и CREATE, если только я не воссоздаю эти вещи (или знаю, что хочу их потерять).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...