PL/SQL-一个人只有一个值
我有下表PL/SQL-一个人只有一个值,sql,oracle,plsql,Sql,Oracle,Plsql,我有下表 CLASS_HAS_STUDENTS ( PER_SSN INTEGER NOT NULL, PER_YEAR INTEGER NOT NULL, /*These two are PKs for a student*/ SCHOOL_CODE INTEGER NOT NULL, /*PK for a school*/ CLASS_YEAR INTEGER NOT NULL, CLASS_NUMBER INTEGER NOT NULL, C
CLASS_HAS_STUDENTS (
PER_SSN INTEGER NOT NULL,
PER_YEAR INTEGER NOT NULL, /*These two are PKs for a student*/
SCHOOL_CODE INTEGER NOT NULL, /*PK for a school*/
CLASS_YEAR INTEGER NOT NULL,
CLASS_NUMBER INTEGER NOT NULL,
CLASS_TEACHTYPE CHAR(3) NOT NULL, /*These three are PKs for a class*/
STUDCLASS_STATUS CHAR(1) NOT NULL
constraint CKC_STUDCLASS_STATUS_CLASS_TI check (StudClass_Status IN ('E', 'Y', 'T', 'P', 'F')),
STUDCLASS_LISTNUMBER INTEGER NOT NULL,
STUDCLASS_ROLLNUMBER INTEGER NOT NULL
);
(此代码缺少一些次要约束)
现在,我需要一种方法来检查每个SSN/每年(一个人的PK)只能有一个“E”(“已注册”)状态。我不能用触发器来做这件事(因为我是从同一个表中选择的),我也不知道我是否可以用check约束来做这件事(我可以在这里使用COUNT()吗?)。感谢您的帮助 我被你的问题弄糊涂了。我猜你要么想: 1) 防止每个学生插入多个状态(在这种情况下,触发器是合适的) 或 2) 使用SELECT语句查找表中已有的学生,在这种情况下,您需要执行以下操作:
SELECT PER_SSN, PER_YEAR, STUDCLASS_STATUS, COUNT(*)
FROM CLASS_HAS_STUDENTS
WHERE STUDCLASS_STATUS = 'E'
HAVING COUNT(*) > 1
GROUP BY PER_SSN, PER_YEAR, STUDCLASS_STATUS;
我被你的问题弄糊涂了。我猜你要么想: 1) 防止每个学生插入多个状态(在这种情况下,触发器是合适的) 或 2) 使用SELECT语句查找表中已有的学生,在这种情况下,您需要执行以下操作:
SELECT PER_SSN, PER_YEAR, STUDCLASS_STATUS, COUNT(*)
FROM CLASS_HAS_STUDENTS
WHERE STUDCLASS_STATUS = 'E'
HAVING COUNT(*) > 1
GROUP BY PER_SSN, PER_YEAR, STUDCLASS_STATUS;
你应该可以用一个简单的方法来做这件事。为了确保每个ssn只有一个注册课程,这应该是可行的:
CREATE UNIQUE INDEX ssn_enrollments ON class_has_students(per_ssn)
WHERE studclass_status='E';
请注意,并非所有SQL实现都支持此功能,但PostgreSQL至少从版本8起就支持此功能。您应该可以使用一个。为了确保每个ssn只有一个注册课程,这应该是可行的:
CREATE UNIQUE INDEX ssn_enrollments ON class_has_students(per_ssn)
WHERE studclass_status='E';
请注意,并非所有SQL实现都支持此功能,但PostgreSQL至少从版本8开始就支持此功能。您可以创建一个基于函数的唯一索引来强制执行此类操作。不能创建这样的约束 这利用了这样一个事实,即Oracle b-tree索引不为空数据编制索引,因此索引将只包含
studclass\u status
为E
的行的条目
CREATE UNIQUE INDEX idx_one_enrolled
ON class_has_students( CASE WHEN studclass_status = 'E'
THEN per_ssn
ELSE null
END,
CASE WHEN studclass_status = 'E'
THEN per_year
ELSE null
END );
您可以创建一个基于函数的唯一索引来执行这类操作。不能创建这样的约束 这利用了这样一个事实,即Oracle b-tree索引不为空数据编制索引,因此索引将只包含
studclass\u status
为E
的行的条目
CREATE UNIQUE INDEX idx_one_enrolled
ON class_has_students( CASE WHEN studclass_status = 'E'
THEN per_ssn
ELSE null
END,
CASE WHEN studclass_status = 'E'
THEN per_year
ELSE null
END );
我想你可以在插入触发器之前使用
。进行一次计数
,如果出现问题,则引发应用程序错误
。你试过了吗?哦,一点也不!!我可以在插入前先插入吗?如果是这样,那么一切都解决了。我去查一下,谢谢!我想你可以在插入触发器之前使用。进行一次计数
,如果出现问题,则引发应用程序错误
。你试过了吗?哦,一点也不!!我可以在插入前先插入吗?如果是这样,那么一切都解决了。我去查一下,谢谢!我想防止每个学生插入一个以上的“E”状态。触发器是合适的,但据我所知,我不能在检查的同一个表上进行选择。我想防止每个学生插入多个“E”状态。触发器是合适的,但据我所知,我不能在我正在检查的同一个表上进行选择。该语法在Oracle中无效,这是问题的标记。这是罪过。我把pl/sql误读为pgsql。不过,解决方案方向仍然有效,我看到Justin Cave提供了一个Oracle-variant。这种语法在Oracle中无效,这是问题的标记。这是罪过。我把pl/sql误读为pgsql。不过,解决方案方向仍然有效,我看到Justin Cave提供了一个Oracle变体。因此,该索引应该取一个人(SSN+年)并检查该人是否已经存在“E”,我说的对吗?@user1231958-它创建了一个唯一的索引,仅当studclass\u状态为E
时,它才会索引每ssn
和每一年的值。这将防止插入两行中的studclass\u状态为E
的值相同的per\u ssn
和per\u year
的两行。它在概念上类似于部分唯一索引,Oracle只是不支持部分唯一索引语法。因此,该索引应该取一个人(SSN+年份)并检查该人是否已经存在“E”,我说的对吗?@user1231958-它创建了一个唯一的索引,仅当studclass\u状态为E
时,它才会索引每ssn
和每一年的值。这将防止插入两行中的studclass\u状态为E
的值相同的per\u ssn
和per\u year
的两行。它在概念上类似于部分唯一索引,Oracle只是不支持部分唯一索引语法。