Comment détecter si une procédure stockée existe déjà


Réponses:


160

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

Ce que je fais, c'est créer une procédure stockée triviale si elle n'existe pas encore. Après cela, vous pouvez MODIFIER la procédure stockée à votre guise.

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

De cette façon, les paramètres de sécurité, les commentaires et autres méta-détails survivront au déploiement.


2
Au moins, si vous le supprimez, vous savez que vous devez rajouter les autorisations. Si vous exécutiez ce SQL, vous ne sauriez pas si le sproc avait les autorisations correctes ou non, car vous ne sauriez pas si vous l'aviez créé ou modifié.
Liazy

@Liazy la solution simple consiste à ajouter du code dans le if object_id('YourSp') is null BEGIN ... ENDpour ajouter les autorisations appropriées après la création de la procédure stockée.
salue le

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

149

La manière la 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 bien faire:

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

CREATE PROC MySproc
AS
BEGIN
    ...
END

1
Cela fonctionnera, mais cela supprime toutes les modifications de sécurité appliquées à la procédure stockée.
Andomar le

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

@EnderWiggin Sauf si l'implémentation de la 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?
Adriaan Davel

2
@AdriaanDavel l c'est à cela que servent les DBA, et amener les DBA à parler aux développeurs s'appelle la gestion. Si les développeurs et les administrateurs de base de données ne peuvent pas travailler ensemble, il y a un problème avec l'entreprise. En outre, les systèmes correctement mis en œuvre ne reposent pas sur le privilège utilisateur pour toucher une base de données, c'est à cela que servent les comptes de service, et la sécurité du niveau de service doit être applicable à l'ensemble de la base de données, de cette façon les administrateurs de base de données n'ont pas à dépenser du temps et de l'argent pour peaufiner la sécurité. sprocs individuels.
Shaun Wilson

2
Je ne voudrais pas que les développeurs abandonnent / recréent des sprocs appartenant à un produit commercial. À bien y réfléchir, je ne demanderais pas non plus aux administrateurs de base de données de faire cela. Je vois cependant ce que vous voulez en venir, c'est-à-dire "et si les administrateurs de base de données ont besoin de modifier la sécurité d'un sproc après le déploiement d'un produit commercial". Je répète que les systèmes correctement mis en œuvre ne reposent pas sur les privilèges des utilisateurs et que la sécurité au niveau du service doit être appliquée à l'ensemble de la base de données. J'ai travaillé avec des administrateurs de base de données qui s'installeront sur un système de démonstration / de travail, puis effectueront une comparaison de schémas pour garantir la sécurité d'une mise à niveau, IMO, c'est ce pour quoi ils sont engagés.
Shaun Wilson

31

Si vous utilisez uniquement des procédures stockées, la chose la plus simple à faire est probablement de supprimer le processus, puis de le recréer. Vous pouvez générer tout le code pour ce 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...

20

De, SQL Server 2016 CTP3vous pouvez utiliser de nouvelles instructions DIE au lieu de gros IFwrappers

Syntaxe:

DROP {PROC | PROCÉDURE} [IF EXISTS] {[schema_name. ] procédure} [, ... n]

Requete:

DROP PROCEDURE IF EXISTS usp_name

Plus d'infos ici


11
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

xxxest le nom du proc


4

En plus de ce qui a déjà été dit, j'aime également ajouter une approche différente et préconiser l'utilisation d'une stratégie de déploiement de scripts différentiels. Au lieu de créer un script avec état qui vérifie toujours l'état actuel et agit en fonction de cet état, déployez via une série de scripts sans état qui sont mis à niveau à partir de versions bien connues . J'ai utilisé cette stratégie et elle est très rentable car mes scripts de déploiement sont désormais tous «IF» gratuits.


Intéressant! Au cours des cinq années écoulées depuis que vous avez publié cette réponse, y a-t-il eu de nouveaux développements dans vos méthodes de contrôle de version de base de données?
Thomas L Holaday

4

Vous pouvez écrire une requête comme suit:

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

CREATE PROCEDURE [dbo].[ProcedureName]
...your query here....

Pour être plus précis sur la syntaxe ci-dessus:
OBJECT_ID est un numéro d'identification unique pour un objet dans la base de données, il est utilisé en interne par SQL Server. Puisque nous passons ProcedureName suivi de votre type d'objet P qui indique au serveur SQL que vous devez trouver l'objet appelé ProcedureName qui est de type procedure, c'est-à-dire P

Cette requête trouvera la procédure et si elle est disponible, elle la supprimera et en créera une nouvelle.

Pour des informations détaillées sur OBJECT_ID et les types d'objets, veuillez visiter: SYS.Objects



0

J'ai un proc stocké qui permet au client d'étendre la validation, s'il existe, je ne veux pas le changer, si ce n'est pas le cas, je veux le créer, de la meilleure façon que j'ai trouvée:

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

2
Je n'ai pas fourni le vote négatif, mais, à une supposition, je dirais qu'il a été voté à la baisse parce que cette solution introduit de nouvelles complications avec l'échappement des guillemets dans le corps de la procédure stockée.
donperk le

0

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

S'il existe, il changera, s'il n'existe pas, il créera 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 @Proc=@Alter + @Proc 

      EXEC (@proc) 
  END 
ELSE 
  BEGIN 
      SET @Proc=@Create + @Proc 

      EXEC (@proc) 
  END 

go 

0

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.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.