2009-06-02 17 views
99

Tengo que escribir una secuencia de comandos de implementación que funcionará si existe o no existe un procedimiento almacenado. es decir, si existe, entonces necesito modificarlo, de lo contrario, crearlo.Cómo detectar si ya existe un procedimiento almacenado

¿Cómo puedo hacer esto en el sql.

estoy usando SQL Server 2005

Respuesta

7

EDIT: no poner texto antes de los bloques de código mata ... Siempre hay que olvidar que :)

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 

donde xxx es el nombre del procedimiento

0

I de acuerdo con Luke, pero una mejor opción podría ser utilizar una herramienta como Red-Gate SQL Compare o SQL Examiner para comparar automáticamente las diferencias y generar un script de migración.

2
IF OBJECT_ID('SPNAME') IS NULL 
    -- Does Not Exists 
ELSE 
    -- Exists 
117

La manera más limpia es comprobar su existencia, soltarla si existe y luego volver a crearla. No puede incrustar una instrucción "create proc" dentro de una instrucción IF. Esto debe hacer muy bien:

IF OBJECT_ID('MySproc', 'P') IS NOT NULL 
DROP PROC MySproc 
GO 

CREATE PROC MySproc 
AS 
BEGIN 
    ... 
END 
+0

Esto funciona, pero elimina cualquier cambio de seguridad aplicadas al procedimiento almacenado. – Andomar

+15

Los cambios de seguridad también deberían formar parte de los scripts. De esa forma, se documentará adecuadamente. Este es el enfoque correcto. –

+0

@EnderWiggin Excepto si la implementación de seguridad no se conoce en el momento del diseño ... ¿Qué sucede si el desarrollador no sabe qué usuarios necesitan derechos de ejecución? –

27

Si se trata únicamente con los procedimientos almacenados, lo más fácil de hacer es probable que deje caer el proc, a continuación, volver a crearlo. Puede generar todo el código para hacer esto usando el asistente Generar secuencias de comandos en 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... 
+2

¡¡¡no te olvides de los permisos !!! tendrás que devolverlos después de crear el sp – opensas

135

Si ABRIGO y CREE el procedimiento, perderá la configuración de seguridad. Esto podría molestar a su DBA o romper su aplicación por completo.

Lo que hago es crear un procedimiento almacenado trivial si aún no existe. Después de eso, puede ALTERAR el procedimiento almacenado a su gusto.

IF object_id('YourSp') IS NULL 
    EXEC ('create procedure dbo.YourSp as select 1') 
GO 
ALTER PROCEDURE dbo.YourSp 
AS 
... 

De esta manera, la configuración de seguridad, los comentarios y otros meta detares sobrevivirán a la implementación.

+2

Al menos si lo sueltas, sabes que tienes que volver a agregar los permisos. Si ejecutó este sql, no sabría si el sproc tenía los permisos correctos o no, ya que no sabría si lo había creado o si lo había alterado. – Liazy

+0

@Liazy la solución simple que hay para agregar código en 'si object_id ('YourSp') es nulo BEGIN ... END' para agregar los permisos adecuados después de crear el procedimiento almacenado. – saluce

+3

piensa que la otra respuesta es un poco más completa, ya que solo extrae la identificación del objeto para los procedimientos almacenados. no es común tener el mismo nombre para diferentes tipos, pero podría suceder – workabyte

3

Además de lo que ya se ha dicho, también me gusta agregar un enfoque diferente y recomendar el uso de la estrategia de implementación de script diferencial. Instead of making a stateful script that always checks the current state and acts based on that state, deploy via a series of stateless scripts that upgrade from well known versions. He utilizado esta estrategia y vale la pena, ya que mis scripts de implementación ahora son todos 'SI' gratuitos.

+0

¡Interesante! En los cinco años transcurridos desde que publicó esta respuesta, ¿ha habido desarrollos posteriores en los métodos de control de versiones de su base de datos? –

0

he un procedimiento almacenado que permite al cliente para extender la validación, si es que existe no quiero cambiarlo, si lo hace, no quiero crearlo, la mejor manera que he encontrado:

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 
+0

¿Por qué no se ha votado? Por favor, no vote abajo sin explicar –

+2

No proporcioné el voto negativo, pero, supongo, diría que se votó negativamente porque esta solución presenta nuevas complicaciones con caracteres de comillas que se escapan dentro del cuerpo del procedimiento almacenado. . – donperk

4

de SQL Server 2016 CTP3 puede utilizar nueva DIE declaraciones en vez de grandes IF envoltorios

sintaxis:

DROP {PROC | PROCEDIMIENTO} [SI EXISTE] {[nombre_esquema. ] procedimiento} [, ...n]

Consulta:

DROP PROCEDURE IF EXISTS usp_name 

Más información here

0

El código de abajo comprobará si el procedimiento almacenado ya existe o no.

Si existe alterará, si no existe se creará un nuevo procedimiento almacenado para usted:

//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 
Cuestiones relacionadas