El método raiserror
raiserror('Oh no a fatal error', 20, -1) with log
Esto terminará la conexión, lo que detendrá la ejecución del resto del script.
Tenga en cuenta que tanto el nivel de gravedad 20 o superior como la WITH LOG
opción son necesarios para que funcione de esta manera.
Esto incluso funciona con declaraciones GO, por ejemplo.
print 'hi'
go
raiserror('Oh no a fatal error', 20, -1) with log
go
print 'ho'
Te dará el resultado:
hi
Msg 2745, Level 16, State 2, Line 1
Process ID 51 has raised user error 50000, severity 20. SQL Server is terminating this process.
Msg 50000, Level 20, State 1, Line 1
Oh no a fatal error
Msg 0, Level 20, State 0, Line 0
A severe error occurred on the current command. The results, if any, should be discarded.
Tenga en cuenta que 'ho' no se imprime.
CUEVAS
- Esto solo funciona si ha iniciado sesión como administrador (rol 'sysadmin') y también lo deja sin conexión a la base de datos.
- Si NO ha iniciado sesión como administrador, la llamada RAISEERROR () fallará y el script continuará ejecutándose .
- Cuando se invoca con sqlcmd.exe, se informará el código de salida 2745.
Referencia: http://www.mydatabasesupport.com/forums/ms-sqlserver/174037-sql-server-2000-abort-whole-script.html#post761334
El método noexec
Otro método que funciona con las declaraciones GO es set noexec on
. Esto hace que se omita el resto del script. No termina la conexión, pero debe noexec
apagarse nuevamente antes de que se ejecute cualquier comando.
Ejemplo:
print 'hi'
go
print 'Fatal error, script will not continue!'
set noexec on
print 'ho'
go
-- last line of the script
set noexec off -- Turn execution back on; only needed in SSMS, so as to be able
-- to run this script again in the same session.
Simplemente use un RETORNO (funcionará tanto dentro como fuera de un procedimiento almacenado).
fuente
Si puede usar el modo SQLCMD, entonces el encantamiento
(INCLUYENDO los dos puntos) hará que RAISERROR detenga realmente el script. P.ej,
dará salida:
y el lote se detendrá. Si el modo SQLCMD no está activado, obtendrá un error de análisis sobre los dos puntos. Desafortunadamente, no es completamente a prueba de balas, ya que si el script se ejecuta sin estar en modo SQLCMD, ¡SQL Managment Studio no pasa por alto los errores de tiempo de análisis! Aún así, si los está ejecutando desde la línea de comandos, está bien.
fuente
No usaría RAISERROR: SQL tiene instrucciones IF que se pueden usar para este propósito. Haga su validación y búsquedas y establezca las variables locales, luego use el valor de las variables en las declaraciones IF para hacer que las inserciones sean condicionales.
No necesitaría verificar un resultado variable de cada prueba de validación. Por lo general, puede hacer esto con solo una variable de indicador para confirmar que se pasaron todas las condiciones:
Incluso si su validación es más compleja, solo debería necesitar algunas variables de marca para incluir en su (s) verificación (es) final (es).
fuente
RAISERROR
, especialmente si no sabe quién ejecutará los scripts y con qué privilegios.declare @i int = 0; if @i=0 begin select '1st stmt in IF block' go end else begin select 'ELSE here' end go
En SQL 2012+, puede usar THROW .
De MSDN:
fuente
Extendí la solución de activación / desactivación de noexec con éxito con una transacción para ejecutar el script de manera todo o nada.
Aparentemente, el compilador "comprende" la variable @finished en el IF, incluso si hubo un error y la ejecución fue deshabilitada. Sin embargo, el valor se establece en 1 solo si la ejecución no se deshabilitó. Por lo tanto, puedo comprometer o revertir la transacción en consecuencia.
fuente
IF (XACT_STATE()) <> 1 BEGIN Set NOCOUNT OFF ;THROW 525600, 'Rolling back transaction.', 1 ROLLBACK TRANSACTION; set noexec on END;
Pero la ejecución nunca se detuvo y terminé con tres errores de "Transacción de retroceso". ¿Algunas ideas?puedes envolver tu declaración SQL en un ciclo WHILE y usar BREAK si es necesario
fuente
DECLARE @ST INT; SET @ST = 1; WHILE @ST = 1; BEGIN; SET @ST = 0; ...; END
Más detallado, pero diablos, de todos modos es TSQL ;-)Puede alterar el flujo de ejecución usando declaraciones GOTO :
fuente
Refinando aún más el método Sglasses, las líneas anteriores fuerzan el uso del modo SQLCMD, y trincan el scirpt si no usan el modo SQLCMD o lo usan
:on error exit
para salir de cualquier errorCONTEXT_INFO se usa para realizar un seguimiento del estado.
fuente
¿Es este un procedimiento almacenado? Si es así, creo que podría hacer una devolución, como "Devolver NULL";
fuente
Sugeriría que envuelva su bloque de código apropiado en un bloque try catch. Luego puede usar el evento Raiserror con una gravedad de 11 para ir al bloque catch si lo desea. Si solo desea aumentar los espejos pero continuar la ejecución dentro del bloque de prueba, use una gravedad menor.
¿Tener sentido?
Saludos, John
[Editado para incluir referencia BOL]
http://msdn.microsoft.com/en-us/library/ms175976(SQL.90).aspx
fuente
puedes usar RAISERROR .
fuente
Ninguno de estos trabajos con declaraciones 'GO'. En este código, independientemente de si la gravedad es 10 u 11, se obtiene la sentencia PRINT final.
Script de prueba:
Resultados:
La única forma de hacer que esto funcione es escribir el script sin
GO
declaraciones. A veces eso es fácil. A veces es bastante difícil. (Usa algo comoIF @error <> 0 BEGIN ...
)fuente
Lo uso
RETURN
aquí todo el tiempo, funciona en script oStored Procedure
Asegúrese de realizar
ROLLBACK
la transacción si está en una, de lo contrario, deRETURN
inmediato se generará una transacción abierta no comprometidafuente
Esta fue mi solución:
...
fuente
Puede usar la declaración GOTO. Prueba esto. Este es el uso completo para ti.
fuente
Gracias por la respuesta!
raiserror()
funciona bien, pero no debe olvidar lareturn
declaración, de lo contrario, el script continúa sin errores. (¡hense que el raiserror no es un "lanzador de terror" ;-)) y, por supuesto, hacer un retroceso si es necesario!raiserror()
Es bueno decirle a la persona que ejecuta el script que algo salió mal.fuente
Si simplemente está ejecutando un script en Management Studio y desea detener la ejecución o la operación de reversión (si se usa) en el primer error, entonces la mejor manera que considero es usar el bloque try catch (SQL 2005 en adelante). Esto funciona bien en Management Studio si está ejecutando un archivo de script. El proceso almacenado siempre puede usar esto también.
fuente
En el pasado utilizamos lo siguiente ... funcionó mejor:
fuente
Adjúntelo en un bloque try catch, luego la ejecución se transferirá a catch.
fuente