Je dois écrire un script de déploiement qui fonctionnera si une procédure stockée existe ou n'existe pas. c'est-à-dire que s'il existe, je dois le modifier, sinon le créer.
Comment puis-je faire cela dans le SQL.
J'utilise SQL Server 2005
Si vous abandonnez et créez la procédure, vous perdrez les paramètres de sécurité. Cela pourrait gêner votre administrateur de base de données ou casser votre application.
Ce que je fais est de 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 convenance.
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 les autres méta-données survivront au déploiement.
Le moyen le plus propre est de tester son existence, de le supprimer s'il existe, puis de le recréer. Vous ne pouvez pas incorporer une instruction "create proc" dans une instruction IF. Cela devrait faire l'affaire:
IF OBJECT_ID('MySproc', 'P') IS NOT NULL
DROP PROC MySproc
GO
CREATE PROC MySproc
AS
BEGIN
...
END
Si vous n'utilisez que des procédures stockées, le plus simple est probablement de supprimer le processus, puis de le recréer. Pour ce faire, vous pouvez générer tout le code à l'aide de l'assistant de génération de 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...
À partir de SQL Server 2016 CTP3
, vous pouvez utiliser les nouvelles instructions DIE au lieu de grands wrappers IF
Syntaxe:
DROP {PROC | PROCEDURE} [IF EXISTS] {[nom_schéma. ] procédure} [ ... n]
Question:
DROP PROCEDURE IF EXISTS usp_name
Plus d'infos ici
EDIT: ne pas mettre du texte avant que les blocs de code ne le tue ... oubliez-le toujours :)
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
En plus de ce qui a déjà été dit, j'aime également ajouter une approche différente et préconiser l'utilisation de la 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-le via une série de scripts sans état qui effectuent une mise à niveau à partir de versions connues . J'ai utilisé cette stratégie et cela en vaut la peine, car mes scripts de déploiement sont désormais entièrement «IF».
IF OBJECT_ID('SPNAME') IS NULL
-- Does Not Exists
ELSE
-- Exists
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 de la base de données, utilisé en interne par SQL Server. Puisque nous passons NomProcédé suivi de votre type d'objetPqui indique à SQL Server que vous devez trouver l'objet appelé NomProcédé qui est de type procédure à savoir, P
Cette requête trouvera la procédure et, si elle est disponible, la supprimera et en créera une nouvelle.
Pour des informations détaillées sur OBJECT_ID et les types d’objet, veuillez visiter:SYS.Objects
J'ai un proc stocké qui permet au client d'étendre la validation, s'il existe je ne veux pas le changer, sinon je veux le créer, le meilleur moyen que j'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
Le code ci-dessous vérifiera si la procédure stockée existe déjà ou non.
Si elle existe, elle va changer, si elle n'existe pas, elle 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 @Proc=@Alter + @Proc
EXEC (@proc)
END
ELSE
BEGIN
SET @Proc=@Create + @Proc
EXEC (@proc)
END
go
Je suis 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.