Estoy escribiendo una función definida por el usuario en SQL Server 2008. Sé que las funciones no pueden generar errores de la manera habitual; si intenta incluir la declaración RAISERROR, SQL devuelve:
Msg 443, Level 16, State 14, Procedure ..., Line ...
Invalid use of a side-effecting operator 'RAISERROR' within a function.
Pero el hecho es que la función toma alguna entrada, que puede ser inválida y, si lo es, no hay un valor significativo que la función pueda devolver. ¿Qué hago entonces?
Podría, por supuesto, devolver NULL, pero sería difícil para cualquier desarrollador que use la función solucionar este problema. También podría causar una división por cero o algo así: esto generaría un mensaje de error, pero uno engañoso. ¿Hay alguna manera de que pueda informar mi propio mensaje de error de alguna manera?
declare @error int; set @error = 'Error happened here.';
El truco habitual es forzar una división entre 0. Esto generará un error e interrumpirá la declaración actual que está evaluando la función. Si el desarrollador o la persona de soporte conocen este comportamiento, investigar y solucionar el problema es bastante fácil ya que el error de división por 0 se entiende como un síntoma de un problema diferente y no relacionado.
Por malo que parezca desde cualquier punto de vista, desafortunadamente el diseño de las funciones SQL en este momento no permite una mejor opción. El uso de RAISERROR debería estar absolutamente permitido en las funciones.
fuente
Siguiendo la respuesta de Vladimir Korolev, el modismo para arrojar un error condicionalmente es
fuente
Creo que la forma más limpia es aceptar que la función puede devolver NULL si se pasan argumentos no válidos. Mientras esto esté claramente documentado, ¿debería estar bien?
fuente
RAISEERROR
o@@ERROR
no están permitidos en UDF. ¿Puedes convertir el UDF en un procedimiento almacenado?Del artículo de Erland Sommarskog Manejo de errores en SQL Server: antecedentes :
fuente
La respuesta principal es generalmente la mejor, pero no funciona para funciones con valores de tabla en línea.
MikeTeeVee dio una solución para esto en su comentario sobre la respuesta principal, pero requirió el uso de una función agregada como MAX, que no funcionó bien para mi circunstancia.
Me equivoqué con una solución alternativa para el caso en el que necesita una tabla en línea con valor udf que devuelve algo como select * en lugar de un agregado. A continuación se muestra un código de muestra para resolver este caso en particular. Como alguien ya ha señalado ... "JEEZ wotta hack" :) ¡ Agradezco cualquier solución mejor para este caso!
fuente
Algunas personas estaban preguntando acerca de cómo generar errores en las funciones con valor de tabla, ya que no se puede usar el tipo de cosas " RETURN [conversión inválida] ". Asignar la conversión no válida a una variable funciona igual de bien.
Esto resulta en:
fuente
No puedo comentar bajo la respuesta de davec con respecto a la función de valor de tabla, pero en mi humilde opinión, esta es la solución más fácil:
fuente
Una forma (un truco) es tener una función / procedimiento almacenado que realice una acción no válida. Por ejemplo, el siguiente pseudo SQL
Donde en la tabla tbl_throw_error, hay una restricción única en la columna err_msg. Un efecto secundario de esto (al menos en MySQL) es que el valor de err_msg se usa como la descripción de la excepción cuando vuelve a subir al objeto de excepción de nivel de aplicación.
No sé si puedes hacer algo similar con SQL Server, pero vale la pena intentarlo.
fuente