Comment puis-je conditionnellement créer une procédure stockée dans SQL Server?
-
09-06-2019 - |
Question
Dans le cadre de ma stratégie d'intégration, j'ai un peu de SQL scripts qui s'exécutent dans l'ordre de mise à jour de la base de données.La première chose que l'ensemble de ces scripts à faire est de vérifier pour voir si ils ont besoin de courir, par exemple:
if @version <> @expects
begin
declare @error varchar(100);
set @error = 'Invalid version. Your version is ' + convert(varchar, @version) + '. This script expects version ' + convert(varchar, @expects) + '.';
raiserror(@error, 10, 1);
end
else
begin
...sql statements here...
end
Fonctionne très bien!Sauf si j'ai besoin d'ajouter une procédure stockée."Créer le proc de la commande" doit être la seule commande dans un lot de commandes sql.Mettre un "créer proc" dans mon instruction SI la cause de cette erreur:
'CREATE/ALTER PROCEDURE' must be the first statement in a query batch.
Ouch!Comment puis-je mettre le CRÉER PROC commande dans mon script, et il ne s'exécutera que si il a besoin d'?
La solution
Voici ce que j'ai trouvé:
L'envelopper dans un EXEC(), comme ceci:
if @version <> @expects
begin
...snip...
end
else
begin
exec('CREATE PROC MyProc AS SELECT ''Victory!''');
end
Fonctionne comme un charme!
Autres conseils
MIS à NOEXEC est une bonne façon de couper une partie de code
IF NOT EXISTS (SELECT * FROM sys.assemblies WHERE name = 'SQL_CLR_Functions')
SET NOEXEC ON
GO
CREATE FUNCTION dbo.CLR_CharList_Split(@list nvarchar(MAX), @delim nchar(1) = N',')
RETURNS TABLE (str nvarchar(4000)) AS EXTERNAL NAME SQL_CLR_Functions.[Granite.SQL.CLR.Functions].CLR_CharList_Split
GO
SET NOEXEC OFF
P. S.Une autre façon est DÉFINIE PARSEONLY { ON | OFF }.
Mais attention aux guillemets à l'intérieur de votre Procédure Stockée - ils besoin d'être "échappé" par l'ajout d'un second.La première réponse qui a fait cela, mais juste au cas où vous l'auriez raté.Un piège pour les jeunes joueurs.
Gestion des versions de votre base de données est la manière de faire, mais...Pourquoi conditionnellement créer des procédures stockées.Pour les Vues, les procédures stockées, les fonctions, tout conditionnellement de les déposer et de les recréer à chaque fois.Si vous conditionnellement créer, alors vous n'aurez pas de nettoyer les bases de données qui ont un problème ou un hack qui a été il y a 2 ans par un autre développeur (vous ou je n'aurais jamais le faire) qui était sûr qu'il allait pas oublier de supprimer l'un d'urgence de mise à jour.
Problème avec la suppression et la création est vous perdez toutes les subventions de sécurité qui ont déjà été appliquées à l'objet d'être supprimé.
Je dois admettre, je l'aurais fait normalement d'accord avec @Peter - je conditionnellement drop et puis sans condition de le recréer à chaque fois.J'ai été pris de trop nombreuses fois dans le passé en essayant de deviner le schéma des différences entre les bases de données, avec ou sans aucune forme de contrôle de version.
Cela dit, votre propre suggestion @Josh est assez cool.Certainement intéressant.:-)
C'est un vieux thread, mais Jobo est incorrect:Création de la Procédure doit être la première instruction dans un lot.Par conséquent, vous ne pouvez pas utiliser Exists
pour tester l'existence et ensuite utiliser Create
ou Alter
.La pitié.
Ma solution est de vérifier si le proc existe, si oui, alors laissons tomber, et puis créer le proc (même réponse que @robsoft mais avec un exemple...)
IF EXISTS(SELECT * FROM sysobjects WHERE Name = 'PROC_NAME' AND xtype='P')
BEGIN
DROP PROCEDURE PROC_NAME
END
GO
CREATE PROCEDURE PROC_NAME
@value int
AS
BEGIN
UPDATE SomeTable
SET SomeColumn = 1
WHERE Value = @value
END
GO
utiliser le "Existe" commande T-SQL pour voir si la procédure stockée existe.Si c'est le cas, utilisez 'Modifier', sinon utiliser "Créer"
IF NOT EXISTS(SELECT * FROM sys.procedures WHERE name = 'pr_MyStoredProc')
BEGIN
CREATE PROCEDURE pr_MyStoredProc AS .....
SET NOCOUNT ON
END
ALTER PROC pr_MyStoredProc
AS
SELECT * FROM tb_MyTable