如何在仅使用 SQL 的 Oracle 中使用枚举? (无 PSQL)
在 MySQL 中你可以这样做:
CREATE TABLE sizes (
name ENUM('small', 'medium', 'large')
);
在 Oracle 中执行此操作的类似方法是什么?
阅读一些有关 MySQL 枚举的内容,我猜最接近的等价物将是一个简单的检查约束
CREATE TABLE sizes (
name VARCHAR2(10) CHECK( name IN ('small','medium','large') )
);
但这不允许您通过索引引用该值。更复杂的外键关系也是可能的
CREATE TABLE valid_names (
name_id NUMBER PRIMARY KEY,
name_str VARCHAR2(10)
);
INSERT INTO valid_sizes VALUES( 1, 'small' );
INSERT INTO valid_sizes VALUES( 2, 'medium' );
INSERT INTO valid_sizes VALUES( 3, 'large' );
CREATE TABLE sizes (
name_id NUMBER REFERENCES valid_names( name_id )
);
CREATE VIEW vw_sizes
AS
SELECT a.name_id name, <<other columns from the sizes table>>
FROM valid_sizes a,
sizes b
WHERE a.name_id = b.name_id
只要通过视图进行操作,似乎就可以很好地复制功能。
现在,如果您承认 PL/SQL 解决方案,您可以创建自定义对象类型,其中可以包含限制它们可以保存的值集的逻辑,并具有获取 ID 和值的方法等。
为什么不对列使用约束?它会做同样的事情:
ALTER TABLE x ADD CONSTRAINT size_constraint 检查 (x_size in ('small', 'medium', 'large'))
在此链接中,您可以找到受 C 语言枚举启发的 Oracle 替代解决方案/解决方法:http://www.petefinnigan.com/weblog/archives/00001246.htm
简而言之,Pete 建议定义一些整数常量并使用 SUBTYPE 来约束它们:
RED constant number(1):=1;
GREEN constant number(1):=2;
BLUE constant number(1):=3;
YELLOW constant number(1):=4;
subtype COLORS is binary_integer range 1..4;
之后您可以使用 COLORS 类型声明变量、传递参数和函数返回值等。
您可以从 Oracle Database 23ai 创建枚举域:
create domain sizes as enum (
small, medium, large
);
这是一份名单。默认情况下,它们的值从 1 开始,每个条目增加 1。
您可以通过像表格一样查询域来查看名称和值:
select * from sizes;
ENUM_N ENUM_VALUE
------ ----------
SMALL 1
MEDIUM 2
LARGE 3
要将表列限制为这些值,请使用枚举作为其数据类型:
create table products (
product_id integer,
product_size sizes
);
您还可以使用
alter table
将枚举添加到现有列,前提是它们具有相同的数据类型。
这添加了隐式检查约束,因此您只能插入枚举中的值:
insert into products values ( 1, 0 );
ORA-11534: check constraint (CHRIS.SYS_C008495) involving column PRODUCT_SIZE due to domain constraint CHRIS.SYS_DOMAIN_C0055 of domain CHRIS.SIZES violated
您还可以按名称引用枚举值。这两个插入物做同样的事情:
insert into products values ( 1, sizes.small );
insert into products values ( 1, 1 );
要查看与存储的枚举值关联的名称,请将列传递给
domain_display
:
select product_id, product_size,
domain_display ( product_size )
from products;
PRODUCT_ID PRODUCT_SIZE DOMAIN
---------- ------------ ------
1 1 SMALL
1 1 SMALL