处理“枚举”有哪些不同的方法? 在 SQL 服务器中?

发布于 2024-07-29 16:52:57 字数 458 浏览 3 评论 0原文

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

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

但是对于许多存储过程来说,这些常量经常会重复,因此存在大量重复。

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

我还有哪些其他选择?

我使用 SQL Server 2008,如果有什么区别的话,我使用 C#。

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

We currently define a list of constants (mostly these correspond to enumerations we have defined in the business layer) at the top of a stored procedure like so:

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

But these often get repeated for many stored procedures so there is a lot of duplication.

Another technique I use if the procedure needs just one or two constants is to pass them in as parameters to the stored procedure. (using the same convention of upper case for constant values). This way I'm sure the values in the business layer and data layer are consistent. This method is not nice for lots of values.

What are my other options?

I'm using SQL Server 2008, and C# if it makes any difference.

Update Because I'm using .Net is there any way that user defined (CLR) types can help?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

⒈起吃苦の倖褔 2024-08-05 16:52:57

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

This might be controversial: my take is don't use enumerations in T-SQL. T-SQL isn't really designed in a way that makes enums useful, the way they are in other languages. To me, in T_SQL, they just add effort and complexity without the benefit seen elsewhere.

故事与诗 2024-08-05 16:52:57

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

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 的按位或)来引用红色和绿色值。

I can suggest two different approaches:

1) Define an Enumeration table with a tinyint identity column as the primary key and the enum value as a unique index; e.g.

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]

Then either:

  • Have your application load the enumeration to primary key value mapping on start-up (assuming this will remain constant).
  • Define a function to translate enumeration values to primary key values. This function can then be used by stored procs inserting data into other tables in order to determine the foreign key to the enumeration table.

2) As per (1) but define each primary key value to be a power of 2. This allows another table to reference multiple enumeration values directly without the need for an additional association table. For example, suppose you define a Colour enumeration table with values: {1, 'Red'}, {2, 'Blue'}, {4, 'Green'}. Another table could reference Red and Green values by including the foreign key 5 (i.e. the bit-wise OR of 1 and 4).

最美的太阳 2024-08-05 16:52:57

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

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

Scalar user define function? Not perfect, but functional...

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
温馨耳语 2024-08-05 16:52:57

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

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

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

I don't like the idea of defining what are effectively constants for stored procedures in multiple places - this seems like a maintenance nightmare and is easily susceptible to errors (typos etc). In fact, I can't really see many circumstances when you would need to do such a thing?

I would definitely keep all enumeration definitions in one place - in your C# classes. If that means having to pass them in to your procedures every time, so be it. At least that way they are only ever defined in one place.

To make this easier you could write some helper methods for calling your procedures that automatically pass the enum parameters in for you. So you call a helper method with just the procedure name and the "variable" parameters and then the helper method adds the rest of the enumeration parameters for you.

把回忆走一遍 2024-08-05 16:52:57

使用标量函数作为常量怎么样? 命名约定将使它们的用法接近枚举:

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

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

...

How about using a scalar function as a constant. A naming convention would make their usage close to enumerations:

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

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

...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文