我在我的数据库中有一个名为" project"的表和一个称为"里程碑"的表。"项目"的主要键是称为ProjectID的列。关系"里程碑"具有一个称为"数字"的主要密钥,而涉及其属于该项目的外键。
当我将新的条目插入"里程碑"时,我希望主键"数字"自动增加,但就新里程碑所属于的项目而言。这个想法基本上是以下内容:
Milestone
ProjectID | Number
69 1
69 2
69 3
420 1
420 2
666 1
420 3
在"里程碑"表中插入值时,可以使用触发器在OraclesQL中实现此目标?
首先,在oracle中命名NUMBER
是一个非常不好的主意,因为这是基本数字类型的名称。我假设您会变得聪明,然后称此PROJECT_LINE
。
您可以使用复合触发器来完成此操作。在BEFORE STATEMENT
触发点中,您可以捕获所有项目的最大项目行(因为在之前的语句部分中,您不知道您要查看的哪个项目),然后在BEFORE EACH ROW
触发点中您将最大值 1分配给新Project_line,然后更新项目最大值的行:
CREATE OR REPLACE TRIGGER MILESTONE_TRG
FOR INSERT ON MILESTONE
COMPOUND TRIGGER
TYPE NUMBER_MAP IS TABLE OF NUMBER
INDEX BY PLS_INTEGER;
tblMAX_PROJECT_LINE NUMBER_MAP; -- store max PROJECT_LINE, indexed by PROJECT_ID
BEFORE STATEMENT IS
BEGIN
tblMAX_PROJECT_LINE := NUMBER_MAP();
FOR aRow IN (SELECT PROJECT_ID,
MAX(PROJECT_LINE) AS MAX_PROJECT_LINE
FROM MILESTONE
GROUP BY PROJECT_LINE)
LOOP
tblMAX_PROJECT_LINE(aRow.PROJECT_ID) := aRow.MAX_PROJECT_LINE;
END LOOP;
END BEFORE STATEMENT;
BEFORE EACH ROW IS
BEGIN
:NEW.PROJECT_LINE := tblMAX_PROJECT_LINE(:NEW.PROJECT_ID) + 1;
tblMAX_PROJECT_LINE(:NEW.PROJECT_ID) := tblMAX_PROJECT_LINE(:NEW.PROJECT_ID) + 1;
END AFTER EACH ROW;
END MILESTONE_TRG;
我不会保证这样做的效率。同样,多个同时插入物可能会发生碰撞。您需要在(Project_ID,Project_line)上放置主密钥或唯一约束,捕获可能在插入语句上发生的密钥违规例外,然后重试插入。
最佳幸运。