2009-06-02 6 views

Répondre

7

EDIT: texte ne pas mettre devant les blocs de code tue ... oublie toujours 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 

où xxx est le nom de proc

0

I d'accord avec Luke mais une meilleure option pourrait être d'utiliser un outil comme Red-Gate SQL Compare ou SQL Examiner pour comparer automatiquement les différences et générer un script de migration.

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

Le moyen le plus propre est de tester son existence, de la supprimer si elle existe, puis de la recréer. Vous ne pouvez pas incorporer une instruction "create proc" dans une instruction IF. Cela devrait faire bien:

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

CREATE PROC MySproc 
AS 
BEGIN 
    ... 
END 
+0

Cela fonctionne, mais il supprime toutes les modifications de sécurité appliquées à la procédure stockée. – Andomar

+15

Les modifications de sécurité doivent également faire partie des scripts. De cette façon, il sera correctement documenté. C'est la bonne approche. –

+0

@EnderWiggin Sauf si l'implémentation de sécurité n'est pas connue au moment de la conception ... Que faire si le développeur ne sait pas quels utilisateurs ont besoin de droits d'exécution? –

27

Si vous traitez uniquement avec les procédures stockées, la meilleure chose à faire est de laisser tomber probablement le proc, puis le recréer. Vous pouvez générer tout le code pour le faire à l'aide de l'Assistant Générer des scripts dans 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

ne pas oublier les autorisations !!! vous devrez leur accorder de nouveau après avoir créé le sp – opensas

135

Si vous supprimez et CRÉEZ la procédure, vous perdrez les paramètres de sécurité. Cela pourrait ennuyer votre DBA ou casser votre application complètement.

Ce que je fais est de créer une procédure stockée trivial si elle n'existe pas encore. Après cela, vous pouvez modifier la procédure stockée à votre goût. De cette façon, les paramètres de sécurité, les commentaires et autres méta-deta survivront au déploiement.

+2

Au moins si vous le déposez, vous savez que vous devez ajouter à nouveau les autorisations. Si vous avez exécuté ce sql, vous ne savez pas si le sproc a les permissions correctes ou non car vous ne savez pas si vous l'avez créé ou modifié. – Liazy

+0

@Liazy la solution simple est d'ajouter du code dans le 'si object_id ('YourSp') est null BEGIN ... END' pour ajouter les permissions appropriées après avoir créé la procédure stockée. – saluce

+3

pense que l'autre réponse est un peu plus complète car elle tire uniquement l'identifiant de l'objet pour les procédures stockées. pas commun d'avoir le même nom pour différents types mais cela pourrait arriver – workabyte

3

En plus de ce qui a déjà été dit, j'aime aussi ajouter une approche différente et préconiser l'utilisation d'une stratégie de déploiement de script différentiel. 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. J'ai utilisé cette stratégie et cela rapporte beaucoup de temps car mes scripts de déploiement sont maintenant tous 'IF' gratuits.

+0

Intéressant! Au cours des cinq années qui ont suivi la publication de cette réponse, avez-vous procédé à d'autres développements dans vos méthodes de contrôle de version de base de données? –

0

J'ai une procédure stockée qui permet au client d'étendre la validation, si elle existe, je ne veux pas changer, si elle ne je veux créer, la meilleure façon que je l'ai trouvé:

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

Pourquoi cela a-t-il été voté? S'il vous plaît ne pas voter sans expliquer –

+2

Je n'ai pas fourni le vote négatif, mais, à première vue, je dirais qu'il a été déclassé parce que cette solution introduit de nouvelles complications avec des caractères de guillemets d'échappement dans le corps de la procédure stockée . – donperk

4

de SQL Server 2016 CTP3 vous pouvez utiliser les nouvelles DIE déclarations au lieu des grandes IF emballages

Syntaxe:

DROP {PROC | PROCEDURE} [IF EXISTS] {[nom_schéma. ] procédure} [, ...n]

Requête:

DROP PROCEDURE IF EXISTS usp_name 

Plus d'info here

0

Le code ci-dessous vérifiera si la procédure stockée existe déjà ou non.

Si elle existe, elle changera, si elle n'existe pas il va créer une nouvelle procédure stockée pour vous:

//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 
Questions connexes