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'?

Était-ce utile?

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

Trouvé ici:https://codereview.stackexchange.com/questions/10490/conditional-create-must-be-the-only-statement-in-the-batch

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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top