2009-06-02 19 views

risposta

7

EDIT: non mettere il testo prima blocchi di codice uccide ... dimentica sempre che :)

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 

dove xxx è il nome proc

0

I d'accordo con Luca, ma una soluzione migliore potrebbe essere quella di utilizzare uno strumento come Red-Gate SQL Compare o SQL Examiner per confrontare automaticamente le differenze e generare uno script di migrazione.

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

Il modo più semplice è testarne l'esistenza, rilasciarlo se esiste e quindi ricrearlo. Non è possibile incorporare un'istruzione "create proc" all'interno di un'istruzione IF. Questo dovrebbe fare bene:

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

CREATE PROC MySproc 
AS 
BEGIN 
    ... 
END 
+0

Questo funzionerà, ma rimuove tutte le modifiche di sicurezza applicate alla stored procedure. – Andomar

+15

Anche le modifiche di sicurezza dovrebbero far parte degli script. In questo modo, verrà adeguatamente documentato. Questo è l'approccio giusto. –

+0

@EnderWiggin Tranne se l'implementazione della sicurezza non è nota in fase di progettazione ... Cosa succede se lo sviluppatore non sa quali utenti necessitano dei diritti di esecuzione? –

27

Se avete a che fare solo con le stored procedure, la cosa più semplice da fare è far cadere probabilmente il proc, quindi ricrearlo. È possibile generare tutto il codice per eseguire questa operazione utilizzando la procedura guidata Genera script in 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

non dimenticare le autorizzazioni !!! dovrai restituirli dopo aver creato lo sp – opensas

135

Se si esegue la procedura DROP e CREA, si perderanno le impostazioni di sicurezza. Ciò potrebbe infastidire il tuo DBA o interrompere del tutto l'applicazione.

Quello che faccio è creare una stored procedure banale se non esiste ancora. Successivamente, è possibile ALTERARE la procedura memorizzata a proprio piacimento.

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

In questo modo, le impostazioni di sicurezza, i commenti e altri meta deta sopravviveranno alla distribuzione.

+2

Almeno se lo fai cadere sai che devi riaggiungere le autorizzazioni. Se hai eseguito questo sql non sapresti se lo sproc aveva i permessi corretti o meno come non sapresti se lo avessi creato o modificato. – Liazy

+0

@Liazy la soluzione semplice è aggiungere codice in "se object_id ('YourSp') è null BEGIN ... END' per aggiungere le autorizzazioni appropriate dopo aver creato la stored procedure. – saluce

+3

pensa che l'altra risposta sia un po 'più completa in quanto tira solo l'ID oggetto per le stored procedure. non è comune avere lo stesso nome per tipi diversi ma potrebbe succedere – workabyte

3

In aggiunta a ciò che è già stato detto, mi piace anche aggiungere un approccio diverso e sostenere l'uso della strategia di distribuzione di script differenziale. 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. Ho usato questa strategia e mi paga molto quando i miei script di implementazione sono ora tutti 'SE' gratuiti.

+0

Interessante! Nei cinque anni da quando hai postato questa risposta, sono stati poi sviluppati ulteriori sviluppi nei metodi di controllo della versione del database? –

0

Ho un proc memorizzato che permette al cliente di estendere la convalida, se esiste io non voglio cambiarlo, se lo fa, non voglio creare, il modo migliore che ho trovato:

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

Perché è stato rifiutato? Si prega di non sottovalutare senza spiegare –

+2

Non ho fornito il down-vote, ma, a occhio e croce, direi che è stato down-votato perché questa soluzione introduce nuove complicazioni con caratteri di citazione di escape all'interno del corpo della stored procedure . – donperk

4

Da SQL Server 2016 CTP3 è possibile utilizzare nuovi DIE dichiarazioni invece di grandi IF involucri

Sintassi:

GOCCIA {PROC | PROCEDIMENTO} [IF EXISTS] {[nome schema. ] procedura} [, ...n]

Query:

DROP PROCEDURE IF EXISTS usp_name 

Maggiori informazioni here

0

Il codice qui sotto controllerà se la stored procedure esiste o no già.

se esiste cambierà, se non esiste, verrà creata una nuova stored procedure per voi:

//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 
Problemi correlati