De la documentation RAISERROR (soulignement le mien):
Les niveaux de gravité de 0 à 18 peuvent être spécifiés par n'importe quel utilisateur. Les niveaux de gravité de 19 à 25 ne peuvent être spécifiés que par les membres du rôle serveur fixe sysadmin ou les utilisateurs disposant des autorisations ALTER TRACE. Pour les niveaux de gravité de 19 à 25, l'option WITH LOG est requise.
Il est fort probable que le principal que vous exécutez le script ne remplit pas ces critères.
Il n'y a rien de mal à utiliser RAISERROR
; vous utilisez simplement un niveau de gravité excessif. J'utilise le niveau 16 par défaut pour une erreur qui est déclenchée et la séquence sera terminée. Si vous voulez être plus précis, vous pouvez suivre les niveaux donnés par Microsoft lui-même:
Maintenant, après avoir dit tout cela, selon le contexte du script, l'utilisation RAISERROR
peut ne pas être suffisante, car elle ne "quitte" pas le script lui-même (en utilisant des niveaux de gravité normaux).
Par exemple:
RAISERROR(N'Test', 16, 1);
SELECT 1; /* Executed! */
Cela provoquera à la fois une erreur et retournera un jeu de résultats.
Pour terminer le script immédiatement, je préfère utiliser RETURN
(l'utilisation de GOTO
constructions de type est généralement déconseillée dans la plupart des cercles de programmation où des alternatives existent):
RAISERROR(N'Test', 16, 1);
RETURN;
SELECT 1; /* Not executed */
Ou gérez l'erreur à l'aide de TRY/CATCH
, ce qui provoquera l'exécution pour sauter au CATCH
bloc si la gravité est 11 ou plus:
BEGIN TRY
RAISERROR(N'Test', 16, 1);
SELECT 1; /* Not executed */
END TRY
BEGIN CATCH
SELECT 2; /* Executed */
END CATCH
BEGIN TRY
RAISERROR(N'Test', 10, 1);
SELECT 1; /* Executed */
END TRY
BEGIN CATCH
SELECT 2; /* Not executed */
END CATCH
Un problème distinct est si le script s'étend sur plusieurs lots - RETURN
ne quittera que le lot :
RAISERROR(N'Test', 16, 1);
RETURN;
SELECT 1; /* Not executed */
GO
SELECT 2; /* Executed! */
Pour résoudre ce problème, vous pouvez vérifier @@ERROR
au début de chaque lot:
RAISERROR(N'Test', 16, 1);
RETURN;
SELECT 1; /* Not executed */
GO
IF (@@ERROR != 0)
RETURN;
SELECT 2; /* Not executed */
Edit: Comme Martin Smith le souligne correctement dans les commentaires, cela ne fonctionne que pour 2 lots. Pour étendre à 3 lots ou plus, vous pouvez cascader des erreurs de génération comme ceci (remarque: la GOTO
méthode ne résout pas ce problème car l'étiquette cible doit être définie dans le lot):
RAISERROR(N'Test', 16, 1);
RETURN;
SELECT 1; /* Not executed */
GO
IF (@@ERROR != 0)
BEGIN
RAISERROR(N'Error already raised. See previous errors.', 16, 1);
RETURN;
END
SELECT 2; /* Not executed */
GO
IF (@@ERROR != 0)
BEGIN
RAISERROR(N'Error already raised. See previous errors.', 16, 1);
RETURN;
END
SELECT 3; /* Not executed */
Ou, comme il le souligne également, vous pouvez utiliser la SQLCMD
méthode si cela convient à votre environnement.