6

我们目前在存储过程的顶部定义了一个常量列表(大部分对应于我们在业务层中定义的枚举),如下所示:

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

但是对于许多存储过程,这些通常会重复,因此存在很多重复。

如果过程只需要一个或两个常量,我使用的另一种技术是将它们作为参数传递给存储过程。(对常量值使用相同的大写约定)。这样我可以确定业务层和数据层中的值是一致的。这种方法不适用于很多值。

我还有哪些其他选择?

我正在使用 SQL Server 2008 和 C#,如果它有什么不同的话。

更新因为我正在使用.Net,用户定义(CLR)类型有什么帮助吗?

4

5 回答 5

3

这可能会引起争议:我的看法是不要在 T-SQL 中使用枚举。T-SQL 的设计方式并没有真正使枚举变得有用,就像它们在其他语言中的方式一样。对我来说,在 T_SQL 中,它们只是增加了工作量和复杂性,而没有其他地方看到的好处。

于 2009-07-29T16:08:32.193 回答
2

标量用户定义函数?不完美,但功能...

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
于 2009-07-29T09:31:02.523 回答
2

我可以建议两种不同的方法:

1) 定义一个以tinyint标识列为主键、枚举值作为唯一索引的枚举表;例如

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]

然后:

  • 让您的应用程序在启动时将枚举加载到主键值映射(假设这将保持不变)。
  • 定义一个函数来将枚举值转换为主键值。然后,存储过程可以使用此函数将数据插入其他表,以确定枚举表的外键。

2)根据(1),但将每个主键值定义为 2 的幂。这允许另一个表直接引用多个枚举值,而无需额外的关联表。例如,假设您使用以下值定义了一个 Color 枚举表:{1, 'Red'}, {2, 'Blue'}, {4, 'Green'}。另一个表可以通过包含外键 5(即 1 和 4 的按位或)来引用红色和绿色值。

于 2009-07-29T08:40:46.073 回答
1

如何使用标量函数作为常数。命名约定将使它们的用法接近枚举:

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

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

...
于 2009-10-13T21:24:12.387 回答
1

我不喜欢在多个地方定义存储过程的有效常量的想法——这似乎是一场维护噩梦,而且很容易出错(错别字等)。事实上,我真的看不出很多情况下你需要做这样的事情?

我肯定会将所有枚举定义保存在一个地方 - 在您的 C# 类中。如果这意味着每次都必须将它们传递给您的程序,那就这样吧。至少这样,它们只在一个地方被定义。

为了使这更容易,您可以编写一些辅助方法来调用自动为您传递枚举参数的过程。因此,您仅使用过程名称和“变量”参数调用辅助方法,然后辅助方法为您添加其余的枚举参数。

于 2009-07-29T09:42:25.433 回答