cómo repensar la misma excepción en sql server
Quiero repensar la misma excepción en sql server que se ha producido en mi bloque try. Puedo lanzar el mismo mensaje pero quiero lanzar el mismo error.
BEGIN TRANSACTION
BEGIN TRY
INSERT INTO Tags.tblDomain
(DomainName, SubDomainId, DomainCode, Description)
VALUES(@DomainName, @SubDomainId, @DomainCode, @Description)
COMMIT TRANSACTION
END TRY
BEGIN CATCH
declare @severity int;
declare @state int;
select @severity=error_severity(), @state=error_state();
RAISERROR(@@Error,@ErrorSeverity,@state);
ROLLBACK TRANSACTION
END CATCH
RAISERROR(@@Error, @ErrorSeverity, @state);
Esta línea mostrará error, pero quiero funcionalidad algo así.
Esto plantea error con el número de error 50000, pero quiero que se lance el número de erron que estoy pasando @@error
,
Quiero capturar este error no en frontend
Es decir,
catch (SqlException ex)
{
if ex.number==2627
MessageBox.show("Duplicate value cannot be inserted");
}
Quiero esto funcionalidad. que no se puede lograr usando raiseerror. No quiero dar un mensaje de error personalizado en el back-end.
RAISEERROR debe devolver el error mencionado a continuación cuando paso errorNo para ser lanzado en catch
Msg 2627, Level 14, State 1, Procedure spOTest_DomainInsert,
Línea 14 Violación de la restricción de CLAVE ÚNICA 'UK_DomainCode'. No se puede insertar duplicar clave en el objeto 'Etiquetas.tblDomain'. La declaración ha sido terminada.
EDITAR:
¿Cuál puede ser el inconveniente de no usar try catch block si quiero que la excepción se maneje en el frontend considerando que el procedimiento almacenado contiene múltiples consultas que deben ejecutarse
10 answers
Aquí hay un ejemplo de código limpio completamente funcional para revertir una serie de instrucciones si se produce un error y reportar el mensaje de error.
begin try
begin transaction;
...
commit transaction;
end try
begin catch
declare @ErrorMessage nvarchar(max), @ErrorSeverity int, @ErrorState int;
select @ErrorMessage = ERROR_MESSAGE() + ' Line ' + cast(ERROR_LINE() as nvarchar(5)), @ErrorSeverity = ERROR_SEVERITY(), @ErrorState = ERROR_STATE();
rollback transaction;
raiserror (@ErrorMessage, @ErrorSeverity, @ErrorState);
end catch
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-09 15:55:53
SQL 2012 introduce la sentencia throw:
Http://msdn.microsoft.com/en-us/library/ee677615.aspx
Si la instrucción THROW se especifica sin parámetros, debe aparecer dentro de un bloque de CAPTURA. Esto hace que la excepción atrapada se eleve.
BEGIN TRY
BEGIN TRANSACTION
...
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
THROW
END CATCH
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-26 00:43:43
Repensando dentro del bloque CATCH (código anterior a SQL2012, use la instrucción THROW para SQL2012 y posteriores):
DECLARE
@ErrorMessage nvarchar(4000) = ERROR_MESSAGE(),
@ErrorNumber int = ERROR_NUMBER(),
@ErrorSeverity int = ERROR_SEVERITY(),
@ErrorState int = ERROR_STATE(),
@ErrorLine int = ERROR_LINE(),
@ErrorProcedure nvarchar(200) = ISNULL(ERROR_PROCEDURE(), '-');
SELECT @ErrorMessage = N'Error %d, Level %d, State %d, Procedure %s, Line %d, ' + 'Message: ' + @ErrorMessage;
RAISERROR (@ErrorMessage, @ErrorSeverity, 1, @ErrorNumber, @ErrorSeverity, @ErrorState, @ErrorProcedure, @ErrorLine)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-13 13:39:12
Creo que sus opciones son:
- No atrape el error (deje que burbujee)
- Levante una personalizada
En algún momento, SQL probablemente introducirá un comando reraise, o la capacidad de detectar solo ciertos errores. Pero por ahora, utilice una solución alternativa. Disculpe....
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-20 00:11:41
No se puede: solo el motor puede lanzar errores de menos de 50000. Todo lo que puede hacer es lanzar una excepción que se parece a...
Ver mi respuesta aquí, por favor,
El interrogador aquí utilizó transacciones del lado del cliente para hacer lo que quería, lo que creo que es un poco tonto...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:30
Ok, esta es una solución...:-)
DECLARE @Error_Number INT
BEGIN TRANSACTION
BEGIN TRY
INSERT INTO Test(Id, Name) VALUES (newID(),'Ashish')
/* Column 'Name' has unique constraint on it*/
END TRY
BEGIN CATCH
SELECT ERROR_NUMBER()
--RAISERROR (@ErrorMessage,@Severity,@State)
ROLLBACK TRAN
END CATCH
Si observa el bloque catch, no está elevando el error, sino devolviendo el número de error real (y también revertiría la transacción). Ahora en su código. NET, en lugar de capturar la exception, si usa ExecuteScalar (), obtiene el número de error real que desea y muestra el número apropiado.
int errorNumber=(int)command.ExecuteScalar();
if(errorNumber=<SomeNumber>)
{
MessageBox.Show("Some message");
}
Espero que esto ayude,
EDITAR: - Solo una nota, si desea obtener el número de registros afectados y tratando de utilizar ExecuteNonQuery, la solución anterior puede no funcionar para usted. De lo contrario, creo que se adaptaría a lo que necesitas. Házmelo saber.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-20 05:52:32
La forma de detener la ejecución en un procedimiento almacenado después de que se haya producido un error y devolver el error al programa que llama es seguir cada instrucción que pueda generar un error con este código:
If @@ERROR > 0
Return
Me sorprendió descubrir que la ejecución en un procedimiento almacenado puede continuar después de un error, sin darme cuenta de esto puede conducir a algunos errores difíciles de rastrear.
Este tipo de manejo de errores parallels (pre. net) Visual Basic 6. Esperando el comando de lanzamiento en SQL Server 2012.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-20 16:58:05
Dado que aún no se ha movido a 2012, una forma de implementar el burbujeo del código de error original es usar la parte de mensaje de texto de la excepción que está (re)lanzando desde el bloque catch. Recuerde que puede contener alguna estructura, por ejemplo, texto XML para que su código de llamada lo analice en su bloque catch.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-25 15:58:57
También puede crear un procedimiento almacenado wrapper para esos escenarios cuando desee que la instrucción SQL se ejecute dentro de la transacción y alimente el error a su código.
CREATE PROCEDURE usp_Execute_SQL_Within_Transaction
(
@SQL nvarchar(max)
)
AS
SET NOCOUNT ON
BEGIN TRY
BEGIN TRANSACTION
EXEC(@SQL)
COMMIT TRANSACTION
END TRY
BEGIN CATCH
DECLARE @ErrorMessage nvarchar(max), @ErrorSeverity int, @ErrorState int
SELECT @ErrorMessage = N'Error Number: ' + CONVERT(nvarchar(5), ERROR_NUMBER()) + N'. ' + ERROR_MESSAGE() + ' Line ' + CONVERT(nvarchar(5), ERROR_LINE()), @ErrorSeverity = ERROR_SEVERITY(), @ErrorState = ERROR_STATE()
ROLLBACK TRANSACTION
RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState)
END CATCH
GO
-- Test it
EXEC usp_Execute_SQL_Within_Transaction @SQL = 'SELECT 1; SELECT 2'
EXEC usp_Execute_SQL_Within_Transaction @SQL = 'SELECT 1/0; SELECT 2'
EXEC usp_Execute_SQL_Within_Transaction @SQL = 'EXEC usp_Another_SP'
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-02 05:44:14
Desde el punto de vista del diseño, ¿cuál es el punto de lanzar excepciones con números de error originales y mensajes personalizados? Hasta cierto punto rompe el contrato de interfaz entre las aplicaciones y la base de datos. Si desea detectar errores originales y manejarlos en código superior, no los maneje en la base de datos. Luego, cuando atrapa una excepción, puede cambiar el mensaje presentado al usuario a cualquier cosa que desee. Yo no lo haría sin embargo, porque hace que su código de base de datos hmm ' no correcto. Como otros dijeron, debería definir un conjunto de sus propios códigos de error (por encima de 50000) y lanzarlos en su lugar. A continuación, puede hanle problemas de integridad ('No se permiten valores duplicados') por separado de los posibles problemas de negocio - 'Código postal no es válido', 'No se encontraron filas que coincidan con los criterios' y así sucesivamente.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-20 13:41:10