2009-07-29 20 views
6

actualmente se define una lista de constantes (en su mayoría éstas corresponden a las enumeraciones que hemos definido en la capa de negocio) en la parte superior de un procedimiento almacenado de este modo:¿Cuáles son las diferentes formas de manejar 'Enumeraciones' en el servidor SQL?

DECLARE @COLOR_RED INT = 1 
DECLARE @COLOR_GREEN INT = 2 
DECLARE @COLOR_BLUE INT = 3 

Pero estos a menudo se repiten para muchos procedimientos almacenados de tal manera hay mucha duplicación.

Otra técnica que uso si el procedimiento necesita solo una o dos constantes es pasarlas como parámetros al procedimiento almacenado. (utilizando la misma convención de mayúsculas para valores constantes). De esta forma, estoy seguro de que los valores en la capa empresarial y la capa de datos son consistentes. Este método no es bueno para muchos valores.

¿Cuáles son mis otras opciones?

Estoy usando SQL Server 2008 y C# si hace alguna diferencia.

Actualización Porque estoy usando .Net ¿hay alguna manera en que los tipos definidos por el usuario (CLR) puedan ayudar?

Respuesta

2

puedo sugerir dos enfoques diferentes:

1) Definir una tabla de enumeración con una columna tinyint identidad como la clave principal y el valor de enumeración como un índice único; p.ej.

CREATE TABLE [dbo].[Market](
     [MarketId] [smallint] IDENTITY(1,1) NOT NULL, 
     [MarketName] [varchar](32) COLLATE Latin1_General_CS_AS NOT NULL, 
CONSTRAINT [PK_Market] PRIMARY KEY CLUSTERED 
(
     [MarketId] ASC 
) ON [PRIMARY] 
) ON [PRIMARY] 

entonces:

  • que su solicitud sea cargar la enumeración de asignación de valores de clave principal en la puesta en marcha (suponiendo que esto se mantendrá constante).
  • Defina una función para traducir valores de enumeración a valores de clave primaria. Esta función puede ser utilizada por procesos almacenados que insertan datos en otras tablas para determinar la clave externa a la tabla de enumeración.

2) Según (1) pero define cada valor de clave primaria como una potencia de 2. Esto permite que otra tabla haga referencia directamente a múltiples valores de enumeración sin la necesidad de una tabla de asociación adicional. Por ejemplo, suponga que define una tabla de enumeración de colores con valores: {1, 'Rojo'}, {2, 'Azul'}, {4, 'Verde'}. Otra tabla podría hacer referencia a los valores Rojo y Verde al incluir la clave externa 5 (es decir, el OR en forma de bit de 1 y 4).

+0

Una clave foránea en las enumeraciones es buena, pero ¿cómo se usan los valores en un procedimiento almacenado? – tpower

+0

@tpower: No estoy del todo seguro de que entienda su pregunta, pero normalmente pasaría los valores de cadena enum en el sproc y los traduciría inmediatamente a claves externas utilizando la función que mencioné. Por lo tanto, la aplicación solo trata con valores enum, el código DB solo trata con los valores de clave foránea. – Adamski

+0

Lo que quiero decir es que si el procedimiento almacenado contiene alguna lógica empresarial como 'IF @ MyVariable = @ MY_ENUMERATION_VALUE_2 THEN' donde necesitamos indicar el valor, las claves externas no ayudan aquí. – tpower

2

usuario escalar definir la función? No es perfecto, pero funcional ...

CREATE FUNCTION dbo.ufnRGB (
    @Colour varchar(20) 
) 
RETURNS int 
AS 
BEGIN 
    DECLARE @key int 

    IF @Colour = 'BLue' 
     SET @key = 1 
    ELSE IF @Colour = 'Red' 
     SET @key = 2 
    ELSE IF @Colour = 'Green' 
     SET @key = 3 

    RETURN @KEy 
END 
1

no me gusta la idea de definir cuáles son las constantes de manera efectiva para procedimientos almacenados en varios lugares - esto parece una pesadilla de mantenimiento y es fácilmente susceptible a errores (errores tipográficos, etc.) De hecho, realmente no puedo ver muchas circunstancias en las que necesitarías hacer tal cosa.

Definitivamente mantendría todas las definiciones de enumeración en un solo lugar: en sus clases de C#. Si eso significa tener que pasarlos a sus procedimientos todo el tiempo, que así sea. Al menos de esa manera solo se definen en un solo lugar.

Para hacerlo más fácil, puede escribir algunos métodos de ayuda para llamar a sus procedimientos que automáticamente pasan los parámetros enum por usted. Entonces llama a un método auxiliar con solo el nombre del procedimiento y los parámetros "variables" y luego el método auxiliar agrega el resto de los parámetros de enumeración por usted.

3

Esto podría ser controvertido: mi opinión es que no use enumeraciones en T-SQL. T-SQL en realidad no está diseñado de manera que haga que las enumeraciones sean útiles, como lo son en otros idiomas. Para mí, en T_SQL, simplemente agregan esfuerzo y complejidad sin el beneficio visto en otra parte.

+1

Acepto, es una base de datos. La asignación entre un nombre y un valor se debe hacer en una tabla. – nocache

1

¿Qué le parece usar una función escalar como constante? Una convención de nomenclatura haría que su uso se acercara a las enumeraciones:

CREATE FUNCTION COLOR_RED() 
RETURNS INT 
AS 
BEGIN 
    RETURN 1 
END 

CREATE FUNCTION COLOR_GREEN() 
RETURNS INT 
AS 
BEGIN 
    RETURN 2 
END 

... 
Cuestiones relacionadas