Как определить, существует ли хранимая процедура
Мне нужно написать развертывание script, которое будет работать, если хранимая процедура существует или не существует. то есть, если он существует, тогда мне нужно его изменить, иначе создайте его.
Как это сделать в sql.
Я использую SQL Server 2005
Ответы
Ответ 1
Если вы DROP и СОЗДАТЬ процедуру, вы потеряете настройки безопасности. Это может раздражать ваш администратор баз данных или вообще полностью нарушать ваше приложение.
Что я делаю, это создать тривиальную хранимую процедуру, если она еще не существует. После этого вы можете ALTER хранимой процедуры по своему усмотрению.
IF object_id('YourSp') IS NULL
EXEC ('create procedure dbo.YourSp as select 1')
GO
ALTER PROCEDURE dbo.YourSp
AS
...
Таким образом, настройки безопасности, комментарии и другие мета-данные останутся в силе.
Ответ 2
Самый чистый способ - проверить его существование, отбросить его, если он существует, а затем воссоздать его. Вы не можете внедрить инструкцию "create proc" внутри оператора IF. Это должно сделать красиво:
IF OBJECT_ID('MySproc', 'P') IS NOT NULL
DROP PROC MySproc
GO
CREATE PROC MySproc
AS
BEGIN
...
END
Ответ 3
Если вы имеете дело только с хранимыми процедурами, самое легкое, что нужно сделать, это, возможно, отказаться от proc, а затем воссоздать его. Вы можете создать весь код для этого, используя мастер создания скриптов в SQL Server.
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[YourSproc]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[YourSproc]
CREATE PROCEDURE YourSproc...
Ответ 4
В SQL Server 2016 CTP3
вы можете использовать новые операторы DIE вместо больших оболочек IF
Синтаксис:
DROP {PROC | PROCEDURE } [ IF EXISTS ] { [ schema_name. ПРОЦЕДУРА} [ЕСЛИ СУЩЕСТВУЕТ] {[имя_схемы. ] процедура} [,... n]
Запрос:
DROP PROCEDURE IF EXISTS usp_name
Больше информации здесь
Ответ 5
if not exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[xxx]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
BEGIN
CREATE PROCEDURE dbo.xxx
где xxx
- имя процесса
Ответ 6
В дополнение к уже сказанному я также хотел бы добавить другой подход и отстаивать использование дифференциальной стратегии развертывания script. Вместо того, чтобы делать stateful script, который всегда проверяет текущее состояние и действует на основе этого состояния, развертывайте через серию скриптов без состояния, которые обновляются из известных версий. Я использовал эту стратегию, и она очень долго платит, так как мои сценарии развертывания теперь полностью свободны от IF.
Ответ 7
IF OBJECT_ID('SPNAME') IS NULL
-- Does Not Exists
ELSE
-- Exists
Ответ 8
Лучшим вариантом может быть использование такого инструмента, как Red-Gate SQL Compare или SQL Examiner, для автоматического сравнения различий и создания сценария миграции.
Ответ 9
У меня есть хранимый процесс, который позволяет клиенту продлить проверку, если он существует, я не хочу его менять, если он не я хочу его создать, лучший способ, который я нашел:
IF OBJECT_ID('ValidateRequestPost') IS NULL
BEGIN
EXEC ('CREATE PROCEDURE ValidateRequestPost
@RequestNo VARCHAR(30),
@ErrorStates VARCHAR(255) OUTPUT
AS
BEGIN
SELECT @ErrorStates = @ErrorStates
END')
END
Ответ 10
В приведенном ниже коде будет проверяться, существует ли хранимая процедура или нет.
Если он существует, он изменится, если он не существует, он создаст для вас новую хранимую процедуру:
//syntax for Create and Alter Proc
DECLARE @Create NVARCHAR(200) = 'Create PROCEDURE sp_cp_test';
DECLARE @Alter NVARCHAR(200) ='Alter PROCEDURE sp_cp_test';
//Actual Procedure
DECLARE @Proc NVARCHAR(200)= ' AS BEGIN select ''sh'' END';
//Checking For Sp
IF EXISTS (SELECT *
FROM sysobjects
WHERE id = Object_id('[dbo].[sp_cp_test]')
AND Objectproperty(id, 'IsProcedure') = 1
AND xtype = 'p'
AND NAME = 'sp_cp_test')
BEGIN
SET @[email protected] + @Proc
EXEC (@proc)
END
ELSE
BEGIN
SET @[email protected] + @Proc
EXEC (@proc)
END
go
Ответ 11
Вы можете написать запрос следующим образом:
IF OBJECT_ID('ProcedureName','P') IS NOT NULL
DROP PROC ProcedureName
GO
CREATE PROCEDURE [dbo].[ProcedureName]
...your query here....
Чтобы быть более точным в приведенном выше синтаксисе:
OBJECT_ID - это уникальный идентификационный номер для объекта в базе данных, он используется внутри SQL Server. Поскольку мы передаем имя_процедуры, за которым следует тип объекта P, который сообщает SQL Server, что вы должны найти объект с именем имя_процедуры, который имеет тип процедуры, т.е. P
Для получения подробной информации о OBJECT_ID и типах объектов, пожалуйста, посетите: SYS.Objects