Pregunta

En la solicitud de que vamos a ser lo que permite a los usuarios escribir en expresiones aritméticas (+ - * /) utilizando otras columnas de base de datos para los números, que luego se pueden analizar por la aplicación y escribe en la base de datos como una columna calculada.

Sin embargo, hay problemas que surgen con lo que permite a los usuarios crear expresiones que podrían hacer excepciones cuando select * la mesa, tales como división por cero, la aritmética-desbordamiento, y posibles otros que no he encontrado todavía (aunque piensan que es todo de ellos).

Tener la base de datos de una excepción en select * sería absolutamente devastador. Yo prefiero tratar de reescribir su expresión en algo que fallaría con gracia si tienen datos propensos a errores.

Para dividir por cero, la solución es bastante sencilla:

add [Col] as case {divisor} when 0 then N'DIVIDE-BY-ZERO' else {expression} end

Mi pregunta es ¿qué puedo hacer yo por desbordamiento aritmético? Mostrando litera o datos erróneos, obviamente, en la columna no sería un problema, pero las excepciones que lanzan haría.

¿Fue útil?

Solución

No me gusta ver que acepte una respuesta que en realidad no llegar más cerca de su objetivo.

Como respuesta por separado que podría ayudarle a salir un poco, puede hacen columnas calculadas llaman un (determinista) UDF escalar.

Véase, por ejemplo, aquí

Así que si usted va a crear una columna calculada, hacerla pasar las columnas a una UDF generado (o varios UDF) y hacer el trabajo allí. En una UDF escalar, puede tener un montón de código para detectar los problemas, pero todavía no se puede utilizar TRY/CATCH. Lo que puede hacer en su UDF es escalar casos capturar y devolver respuestas apropiadas (burbujeando NULL, probablemente).

Sin embargo, el rendimiento será muy pobres en las UDF escalares (no estoy seguro acerca de las columnas calculadas en línea no persistente frente a las UDF, que utilizan principalmente persisted), por lo que podría seriamente desee considerar la posibilidad de la columna se mantuvo , que a su vez utilizar el espacio en la base de datos y hacer las inserciones y actualizaciones un poco más lento. Esa es una gran desventaja.

Otros consejos

Ya que has analizar la tecnología, se puede volver a escribir las expresiones para atrapar todos los problemas potenciales con un montón de instrucciones CASE -. División por cero, se desborda, upcasting de diferentes tipos, etc.

Pero yo no haría eso, porque no creo que ponerlos en la base de datos como parte del esquema es una gran idea, a menos que esta herramienta es una herramienta de generación de código nd usuarios son responsables de revisar y probar el expresiones para condiciones de borde igual que si se incluyeron en el diseño de base de datos original.

Si ya está analizando la expresión, me gustaría recopilar esta en el lado del cliente, también, y controlar el error de forma fila por fila.

La captura la excepción usando TRY / CATCH es un escenario de todo o nada, no sobre una base de fila por fila.

¿Qué hay de la captura de las excepciones? Parece difícil de tratar de detectar todas las posibles causas de desbordamiento aritmético, por no hablar de excepciones en general.

En excepciones, se puede devolver un conjunto de resultados sin sentido que sea compatible con el original definida por el usuario uno:

begin try
    select exp(999)
end try
begin catch
    select 1
end catch 

Si el rendimiento es importante, utilizar un disparador o vista indizada para almacenar los cálculos cuando los datos se inserta, actualiza o se elimina.

Si el rendimiento no es importante, utilizar una función con valores escalares.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top