2008-12-01 22 views

Respuesta

-7

La validación de parámetros no es actualmente una característica de la lógica de procedimientos en SQL Server, y NOT NULL es solo un posible tipo de validación de datos. El tipo de datos CHAR en una tabla tiene una especificación de longitud. ¿Debería implementarse también? ¿Y cómo manejas las excepciones? Existe una metodología extensa, altamente desarrollada y algo basada en estándares para el manejo de excepciones en esquemas de tablas; pero no para la lógica procedimental, probablemente porque la lógica procedimental se define a partir de los sistemas relacionales. Por otro lado, los procedimientos almacenados ya tienen un mecanismo existente para generar eventos de error, vinculados a numerosas API e idiomas. No hay tal soporte para restricciones de tipo de datos declarativos en los parámetros. Las implicaciones de agregarlo son extensas; especialmente porque está bien soportado, y extensible, simplemente agregar el código:

IF ISNULL(@param) THEN 
    raise error .... 
END IF 

El concepto de NULL en el contexto de un procedimiento almacenado no está aún bien definido especialmente en comparación con el contexto de una mesa o una expresión SQL. Y no es la definición de Microsoft. Los grupos de estándares SQL han pasado muchos años generando mucha literatura que establece el comportamiento de NULL y los límites de las definiciones para ese comportamiento. Y los procedimientos almacenados no son uno de ellos.

Un procedimiento almacenado está diseñado para ser tan liviano como sea posible para que el rendimiento de la base de datos sea lo más eficiente posible. Los tipos de datos de los parámetros no están ahí para la validación, sino para permitir que el compilador proporcione al optimizador de consultas mejor información para compilar el mejor plan de consulta posible. Una restricción NOT NULL en un parámetro se dirige hacia abajo en una ruta completa al hacer que el compilador sea más complejo con el nuevo propósito de validar argumentos. Y por lo tanto, menos eficiente y más pesado.

Hay una razón por la que los procedimientos almacenados no se escriben como funciones de C#.

+43

* "por qué debería ser posible" * - Ummm ... porque es un atajo muy común en la instrucción 'CREATE TABLE', entonces * no * tenerlo para' CREATE PROCEDURE' es inconsistente? ¿Qué tan difícil sería para SQL Server comprobar el parámetro null de la misma manera que lo hace para las columnas de la tabla? –

+0

'NOT NULL' _es_ parte del tipo de datos.Piense en ello como 'nulable' frente a 'no nulo'. Uno es un tipo que contiene todos los valores 'estándar', y también incluye un valor de caso NULL especial. El otro contiene solo los valores "estándar". Los dos tipos se basan en los mismos valores subyacentes, pero uno proporciona un caso especial. –

+0

NOT NULL no es parte del tipo de datos. Es parte de la definición de columna para una tabla. NULL es sin tipo. No existe un concepto como NULL INTEGER o NULL VARCHAR. Sí, es parte de la DDL para afirmar una columna en una tabla. También lo es DEFAULT, y también lo son las definiciones de índice y clave externa. ¿Estamos diciendo que los parámetros del procedimiento almacenado se deben considerar ortogonales con columnas de tabla? – dkretz

39

Puede verificar su NULL-ness en el sproc y RAISERROR para informar el estado a la ubicación de la llamada.

CREATE proc dbo.CheckForNull @i int 
as 
begin 
    if @i is null 
    raiserror('The value for @i should not be null', 15, 1) -- with log 

end 
GO 

luego llamar a:

exec dbo.CheckForNull @i = 1 

o

exec dbo.CheckForNull @i = null 
+0

Esperando que alguien actualice esta respuesta para aceptar un nombre de parámetro opcional para el mensaje de error, acepte todos los tipos comunes (bigint, varchar, ... y suba solo si todos son nulos). – crokusek

10

Su código es correcto, sensible e incluso buenas prácticas. Solo necesita esperar SQL Server 2014 que admite este tipo de sintaxis.

Después de todo, ¿por qué atrapar en tiempo de ejecución cuando puede en tiempo de compilación?

Vea también this msdn document y busque Natively Compiled allí.

Como dice dkrez, nullabiliy no se considera parte de la definición del tipo de datos. Todavía me pregunto por qué no.

Cuestiones relacionadas