У меня есть сценарий SQL, который должен запускаться каждый раз, когда клиент выполняет функцию «управления базой данных». Сценарий включает в себя создание хранимых процедур в клиентской базе данных. Некоторые из этих клиентов могут уже иметь хранимую процедуру при запуске сценария, а некоторые - нет. Мне нужно добавить отсутствующие хранимые процедуры в клиентскую базу данных, но не важно, насколько я пытаюсь изменить синтаксис T-SQL, я получаю
CREATE / ALTER PROCEDURE 'должен быть первым оператором в пакете запроса
Я прочитал об этом перед созданием работ, но мне не нравится делать это таким образом.
IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'MyProc')
DROP PROCEDURE MyProc
GO
CREATE PROCEDURE MyProc
...
Как добавить проверку на наличие хранимой процедуры и создать ее, если она не существует, но изменить ее, если она существует?
sql
sql-server
tsql
stored-procedures
Формирователь
источник
источник
Ответы:
Вы можете запускать процедурный код везде, где можете выполнить запрос.
Просто скопируйте все после
AS
:Этот код выполняет те же действия, что и хранимый процесс, но не хранится на стороне базы данных.
Это очень похоже на то, что называется анонимной процедурой в
PL/SQL
.Обновить:
Название вашего вопроса немного сбивает с толку.
Если вам нужно только создать процедуру, если она не существует, тогда ваш код в порядке.
Вот что
SSMS
выводится в скрипте создания:Обновить:
Пример того, как это сделать при включении схемы:
В приведенном выше примере dbo - это схема.
Обновить:
В SQL Server 2016+ вы можете просто
CREATE OR ALTER PROCEDURE dbo.MyProc
источник
@astander
: вы также можете вызвать анонимный код из хранимых процедур. Чтобы использовать их вывод в anINSERT
, вам нужно использоватьOPENROWSET
илиOPENQUERY
который работает с анонимным кодом. Конечно, есть недостатки в анонимном коде: например, он работает только под привилегиями вызывающего. Моя точка зрения заключается в том, что это возможно, а не предпочитаемый способ ведения дел :)Я понимаю, что это уже помечено как ответ, но мы делали это так:
Просто чтобы не уронить процедуру.
источник
GRANT
явной форме заявления , содержащиеся в сценарии в случае , если они изменить ; так что все еще есть оправдание для использованияDROP
вместоALTER
.Если вы ищете самый простой способ проверить существование объекта базы данных перед его удалением, вот один из способов (в примере используется SPROC, как и в предыдущем примере, но его можно изменить для таблиц, индексов и т. Д.):
Это быстро и элегантно, но вы должны убедиться, что у вас есть уникальные имена объектов для всех типов объектов, так как это не учитывает это.
Надеюсь, это поможет!
источник
Я знаю, что вы хотите «изменить процедуру, если она существует, и удалять ее только в том случае, если она не существует», но я считаю, что проще всегда просто отбросить процедуру, а затем воссоздать ее. Вот как можно отбросить процедуру, только если она уже существует:
Второй параметр указывает
OBJECT_ID
только искать объекты сobject_type = 'P'
, которые хранимых процедур:Вы можете получить полный список опций через:
источник
С SQL Server 2016 вы можете использовать новый
DROP PROCEDURE IF EXISTS
.DROP { PROC | PROCEDURE } [ IF EXISTS ] { [ schema_name. ] procedure } [ ,...n ]
Ссылка: https://msdn.microsoft.com/en-us/library/ms174969.aspx
источник
Я знаю, что это очень старая публикация, но поскольку она появляется в верхних результатах поиска, следовательно, добавляется последнее обновление для тех, кто использует SQL Server 2016 SP1 -
Это создает хранимую процедуру, если она еще не существует, но изменяет ее, если она существует.
Ссылка
источник
DROP IF EXISTS - это новая функция SQL Server 2016
https://blogs.msdn.microsoft.com/sqlserverstorageengine/2015/11/03/drop-if-exists-new-thing-in-sql-server-2016/
источник
У меня была такая же ошибка. Я знаю, что этот поток уже практически мертв, но я хочу установить другую опцию, кроме "анонимной процедуры".
Я решил это так:
Проверьте, существует ли хранимая процедура:
Однако
"CREATE/ALTER PROCEDURE' must be the first statement in a query batch"
это все еще там. Я решил это так:Я в конечном итоге с этим кодом:
источник
Вот метод и некоторые аргументы за его использование. Редактировать сохраненный процесс не так приятно, но есть плюсы и минусы ...
ОБНОВЛЕНИЕ: Вы можете также обернуть весь этот вызов в СДЕЛКУ. Включая множество хранимых процедур в одну транзакцию, которая может зафиксировать или откатить все. Еще одним преимуществом переноса транзакции является то, что хранимая процедура всегда существует для других соединений SQL, если они не используют уровень изоляции транзакции READ UNCOMMITTED!
1) Избегать изменений просто как процесс принятия решения. Наши процессы должны всегда, ЕСЛИ СУЩЕСТВУЕТ, ТО, ЧЕМ СОЗДАТЬ. Если вы сделаете то же самое, предполагая, что новый PROC является желаемым процессом, обслуживание изменений будет немного сложнее, потому что у вас будет IF EXISTS ALTER ELSE CREATE.
2) Вы должны поместить CREATE / ALTER в качестве первого вызова в пакете, чтобы вы не могли обернуть последовательность обновлений процедур в транзакции вне динамического SQL. В основном, если вы хотите запустить целый стек обновлений процедур или откатить их все назад, не восстанавливая резервную копию БД, это способ сделать все в одном пакете.
источник
В SQL Server 2008 года вы можете использовать "
INFORMATION_SCHEMA.ROUTINES
"источник
Очевидно, у меня нет репутации, необходимой для голосования или комментирования, но я просто хотел сказать, что ответ Джеффа с использованием EXEC (sp_executesql может быть лучше) определенно является подходящим вариантом. Удаление и последующее воссоздание хранимой процедуры завершает работу, но есть момент, когда хранимая процедура вообще не существует, и это может быть очень плохо, особенно если это что-то, что будет бегать многократно. У меня были всевозможные проблемы с моим приложением, потому что фоновый поток выполнял IF EXISTS DROP ... CREATE в то же время, когда другой поток пытался использовать хранимую процедуру.
источник
** Самый простой способ удалить и воссоздать сохраненный процесс в T-Sql это **
источник
Вот сценарий, который я использую. Благодаря этому я избегаю ненужного сброса и воссоздания сохраненных процедур.
источник
Проверьте, если существует для хранимой процедуры
Проверьте, если существует для триггера, функция также нажав ссылку ниже http://www.gurujipoint.com/2017/05/check-if-exist-for-trigger-function-and.html
источник
почему бы тебе не пойти простым путем, как
..........
источник
%
, поэтомуLIKE
ведет себя как=
В дополнение к ответу @Geoff я создал простой инструмент, который генерирует SQL-файл, который содержит операторы для хранимых процедур, представлений, функций и триггеров.
Смотрите MyDbUtils @ CodePlex .
источник
Я думаю! Почему я не пишу весь запрос, как
я уже знаю, что первые две процедуры уже существуют, sql выполнит запрос, выдаст ошибку первых двух процедур, но все же он создаст последнюю процедуру, SQl сама заботится о том, что уже существует, это то, что я всегда делаю со всеми своими клиенты!
источник
CREATE Процедура, ЕСЛИ НЕ СУЩЕСТВУЕТ 'Ваше имя-процесса' () НАЧИНАЕТСЯ ... КОНЕЦ
источник