2009-12-18 5 views
5

Estamos agregando algunos procedimientos almacenados a nuestro producto que pueden ser llamados por clientes de terceros. ¿Existen mejores prácticas para la validación de parámetros, valores de retorno, RAISERROR, etc.?¿Mejores prácticas para la API de procedimiento almacenado?

Los clientes de terceros no tendrán acceso directo a la tabla, solo a ciertos sprocs. La tabla tocada por los sprocs está bien restringida, pero queremos ser tan amigables como sea posible en cuanto a proporcionar información de error detallada cuando los sprocs se llaman incorrectamente.

+1

¡Gran pregunta! –

Respuesta

2

No es difícil proporcionar mensajes de error informativos que un humano pueda entender. Solo RAISERROR con un texto descriptivo. Un poco más difícil es levantar textos localizados, lo que implica el uso apropiado de sp_addmessage y familia. El verdadero problema difícil es generar errores a los que un programa puede reaccionar. Esto significa códigos de error debidamente documentados (y gravedad y estado), y disciplina de código severa al usarlos en su API.

Y no se olvide de anidar la transacción adecuada. Tengo una muestra en mi blog sobre cómo manejar adecuadamente las transacciones en combinación con las excepciones de T-SQL: Exception handling and nested transactions.

Desafortunadamente, el estado de la técnica en el conjunto de la pila de cliente/T-SQL frente a la excepción tiene algunos problemas. Lo más notable es que si detecta una excepción de T-SQL, no puede volver a lanzarla, por lo que su cliente no puede esperar los típicos números de error del sistema. Ver SQL Server: Rethrow exception with the original exception number. Esto le deja pocos medios para comunicar información de error adecuada, además de usar sus propios números de error en el rango de más de 50000, que es muy engorroso a medida que aumenta el número de códigos de error "transalated" y utilizando la cadena de mensaje de error como información de excepción .

+0

¿Existen problemas de interoperabilidad con clientes que no son de Windows, por ejemplo, clientes * nix que usan FreeTDS? Hay poca mención del manejo RAISERROR en sus documentos. –

+0

No es que yo sepa. RAISERROR plantea el mismo tipo de error que los errores del sistema, y ​​FreeTDS sabe cómo manejarlos. –

3
  • Use bloques try/catch
  • Throw mensajes significativos (yo uso un prefijo como "INFO:" para distinguir mis errores de errores de base de datos)

Ejemplo:

SET NOCOUNT, XACT_ABORT ON 
... 
BEGIN TRY 
    IF @parameter1 IS NULL 
     RAISERROR ('INFO: "parameter1" should not be blank', 16, 1) 

    IF @parameter2 < 0 
     RAISERROR ('INFO: "parameter2" must be greate then zero', 16, 1) 

    ... 

END TRY 
BEGIN CATCH 
    DECLARE @MyError nvarchar(2048) 
    SELECT @MyError = ERROR_MESSAGE() -- + other stuff, like stored proc name perhaps 
    RAISERROR (@MyError, 16, 1) 
    ... 
END CATCH 
+1

Debe hacer un estado diferente cada RAISERROR: (..., 16, ** 1 **), (..., 16, ** 2 **), (..., 16, ** 3 **) De esta forma, cuando un cliente llama al soporte y proporciona una información de error (mensaje, código, gravedad, estado), el soporte puede localizar rápidamente el lugar donde se produjo el error, que es exactamente el propósito del estado. –

+0

Lo hacemos un poco más complejo, incluido el registro de cada error y la separación de ERROR de INFO. Objeto de registro, objeto de error, número de línea, etc. Pero: separamos los errores reales de "oops, duplicate value" que son informativos y no realmente errores – gbn

Cuestiones relacionadas