在SQL中模拟枚举?

时间:2009-06-08 11:28:59

标签: sql-server tsql

我最近意外地写了一个非常难看的存储过程,我希望我有枚举,

EG。

CREATE PROCEDURE Proc_search_with_enum @user int, @account_category {enum}

据我所知,SQL 2000没有枚举作为第一类语言结构,您使用哪种编码约定来模拟枚举或以其他方式解决同一问题?

或者我是否注定只使用VARCHAR和IF @ account_category ='cat1'?

编辑:T-SQL和C#是客户端语言。

编辑:谢谢大家!很多好建议,我希望我能接受几个答案,我已经投了大家 -

答案摘要

  • 使用int在C#的枚举上倾斜。好 对于C#客户端代码,制作TSQL客户端 代码不太可读。
  • 使用Char / Varchar。 C#客户端代码不好 (不适合本地化),制作 TSQL代码更具可读性。
  • 使用参数检查代码进行限制 参数,或使用约束 表列或外键if 该参数将被插入 进入一张桌子。

9 个答案:

答案 0 :(得分:11)

您可以查看this question的答案。据我所知,枚举类型不是SQL Server的一部分。

无论如何,最好为枚举使用整数(INTTINYINT,...)类型而不是字符串类型。通常,您选择的编程语言中的枚举类型更好地对应于整数而不是字符串。

在C#中,默认情况下每个枚举值对应一个整数,从0开始。你甚至可以在它们之间进行转换,所以这是有效的代码:

public enum MyEnum
{
    FirstEnumValue,
    SecondEnumValue
}

...

// Assuming you have opened a SqlDataReader.
MyEnum enumValue = (MyEnum) reader["account_category"];

LINQtoSQL也支持这一点。如果您有一个枚举类型的属性,并且您的数据库列是整数类型,则转换是自动的。

答案 1 :(得分:2)

在PostgreSql中,我只使用附加约束的VARCHAR ......

CREATE TABLE movie_clip (        
    type VARCHAR(40) NULL CHECK(type IN ('trailer', 'commercial')),
);

#=> insert into movie_clip (type) values ('trailer');
INSERT 0 1
#=> insert into movie_clip (type) values ('invalid value');
ERROR:  new row for relation "movie_clip" violates check constraint "movie_clip_type_check"

#=> \d movie_clip
....
"movie_clip_type_check" CHECK (type::text = ANY (ARRAY['trailer'::character varying, 'commercial'::character varying]::text[]))

我不喜欢使用数字类型来模拟ENUM,因为它们不够具有描述性。通过上面的模式,我可以立即看到它接收到的可能值,并且我也可以立即获得这些值的含义。我也得到了类型安全性,因为我无法在该列中插入无效值。

有关Postgres约束的更多详细信息,请参阅此处: http://www.postgresql.org/docs/8.1/static/ddl-constraints.html

答案 2 :(得分:2)

我通常更喜欢调用参数@account_category_code并使其成为CHAR(3),如果只有几个枚举值并且它们都可以用三个字母干净地表达。然后使用检查约束强制执行域。如果有多个值(大于4或5),那么我通常会切换到名为@account_category_type_id的tinyint / smallint,并有一个域表来引用它。我们的组织中没有严格的规则,但我觉得这很有效。

答案 3 :(得分:1)

有时CHAR类型比INT更有用 - 固定大小的char不占用太多存储空间,您可以直接在数据库字段中看到“枚举”值。与代码方没有区别,但在直接使用SQL工具时有很大的进步。

答案 4 :(得分:1)

在使用CHAR类型进行枚举时要格外小心,如果你想让你的app / db走向国际,请完全避免使用它。
不要将DATA与它的表示混淆:就像单词应该建议的那样,枚举(eration)是一个数字,它的描述是完全不同的业务。为简短起见,使用CHAR变量/字段作为枚举,您可以将自己绑定到特定语言以进行描述:例如,您可以忘记国际化。你能想象“Weltmeisterschaft”这个词是什么意思,用哪种语言 - 而且 - 有多少不同的写错方式可以? 实际上,一个(微小的)int实际上是价值的缺点,而不是内在的自动描述:我没有说它是完美的解决方案!

答案 5 :(得分:1)

在SQL中,您可以通过将项目放入表中来枚举项目。为您的帐户类别创建一个查找表,并让此参数接受新表的主键。

答案 6 :(得分:1)

答案 7 :(得分:0)

在Transact-SQL中执行此操作的最简单方法是使用CHECK约束。您可以详细了解herehere。 PostgreSQL和Oracle也可以使用此约束。

答案 8 :(得分:0)

您可以使用CASE statement

要从结果集创建枚举示例,您可以执行以下操作:

SELECT
    FirstName,
    LastName,
    CASE JobTitle WHEN 0 THEN 'Software Developer' WHEN 1 THEN 'Software Architect' WHEN 2 THEN 'President' ELSE 'Staff' END AS 'Job Title',
    Salary
FROM
    Employees

你基本上通过SWITCH语句之类的东西运行一个整数。将它放在存储过程中,这样就不必反复编写相同的代码。希望这会有所帮助。enter code here