Eu tenho que escrever um script de implantação que funcione se um procedimento armazenado existir ou não. ou seja, se existir, preciso alterá-lo, caso contrário, criá-lo.
Como posso fazer isso no sql.
Estou usando o SQL Server 2005
Eu tenho que escrever um script de implantação que funcione se um procedimento armazenado existir ou não. ou seja, se existir, preciso alterá-lo, caso contrário, criá-lo.
Como posso fazer isso no sql.
Estou usando o SQL Server 2005
Respostas:
Se você soltar e criar o procedimento, perderá as configurações de segurança. Isso pode incomodar seu DBA ou interromper completamente seu aplicativo.
O que faço é criar um procedimento armazenado trivial, se ainda não existir. Depois disso, você pode ALTERAR o procedimento armazenado ao seu gosto.
IF object_id('YourSp') IS NULL
EXEC ('create procedure dbo.YourSp as select 1')
GO
ALTER PROCEDURE dbo.YourSp
AS
...
Dessa forma, as configurações de segurança, os comentários e outras meta deta sobreviverão à implantação.
if object_id('YourSp') is null BEGIN ... END
para adicionar as permissões apropriadas após a criação do procedimento armazenado.
A maneira mais limpa é testar sua existência, descartá-la, se existir, e depois recriá-la. Você não pode incorporar uma instrução "create proc" dentro de uma instrução IF. Isso deve fazer bem:
IF OBJECT_ID('MySproc', 'P') IS NOT NULL
DROP PROC MySproc
GO
CREATE PROC MySproc
AS
BEGIN
...
END
Se você estiver lidando apenas com procedimentos armazenados, a coisa mais fácil a fazer é provavelmente largar o proc e depois recriá-lo. Você pode gerar todo o código para fazer isso usando o assistente para gerar scripts no 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...
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
onde xxx
é o nome do proc
Além do que já foi dito, também gosto de adicionar uma abordagem diferente e advogar o uso da estratégia de implantação de scripts diferenciais. Em vez de criar um script com estado que sempre verifique o estado atual e atue com base nesse estado, implante por meio de uma série de scripts sem estado que são atualizados a partir de versões conhecidas . Eu usei essa estratégia e vale muito a pena, pois meus scripts de implantação agora estão todos 'SE' livres.
Você pode escrever uma consulta da seguinte maneira:
IF OBJECT_ID('ProcedureName','P') IS NOT NULL
DROP PROC ProcedureName
GO
CREATE PROCEDURE [dbo].[ProcedureName]
...your query here....
Para ser mais específico na sintaxe acima:
OBJECT_ID é um número de identificação exclusivo para um objeto no banco de dados, usado internamente pelo SQL Server. Como estamos passando o ProcedureName seguido pelo seu tipo de objeto P, que informa ao SQL Server que você deve encontrar o objeto chamado ProcedureName, que é do tipo procedure, ou seja, P
Esta consulta encontrará o procedimento e, se estiver disponível, descartará e criará um novo.
Para informações detalhadas sobre OBJECT_ID e tipos de objeto, visite: SYS.Objects
IF OBJECT_ID('SPNAME') IS NULL
-- Does Not Exists
ELSE
-- Exists
Eu tenho um procedimento armazenado que permite ao cliente estender a validação; se existir, não quero alterá-lo; se não, quero criá-lo, da melhor maneira que encontrei:
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
O código abaixo verificará se o procedimento armazenado já existe ou não.
Se existir, ele será alterado, se não existir, criará um novo procedimento armazenado para você:
//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 @Proc=@Alter + @Proc
EXEC (@proc)
END
ELSE
BEGIN
SET @Proc=@Create + @Proc
EXEC (@proc)
END
go