Oracle:使用Trigger和Loop自动分配值

时间:2014-04-23 18:30:25

标签: sql oracle for-loop triggers

我目前正在开发一个模拟护理院数据库的项目。所以我想要的是如果一个新的居民进入数据库,触发器将触发并循环通过房间数,直到它找到一个房间,其中居住者具有空值。然后,触发器应将新的resid.id设置为占用者值,将room_num设置为新驻留行上的room_num值。当然,如果for循环找不到空房,它应该输出一条消息说明。

我为我的懒人代码道歉,但是我一直在搞乱这个问题并且没有得到任何结果。目前我当前的错误是

Error at line 6: PL/SQL: ORA-00923: FROM keyword not found where expected

非常感谢你们可爱的人提供的任何帮助!

Create OR REPLACE TRIGGER Room_Assign
BEFORE INSERT ON Residents
FOR EACH ROW

BEGIN
FOR Room_Num in 1..MAX(Room_Num) loop
if Rooms.Occupant = NULL
THEN
update Rooms Set Occupant = new.Resid_ID where Occupant = NULL;
SELECT Rooms.Room_Num INTO Residents.Room_Num;
Exit;

END IF;
END loop;
IF new.Resid_ID = NULL
 DBMS_OUTPUT.PUT_LINE("There are no vacant rooms.")
 END;
 /

2 个答案:

答案 0 :(得分:2)

在任何一种企业中,即使是“我自己有趣的小项目”的企业,这也是“如何通过添加触发器使应用程序无法使用”的一个主要例子。

不要使用触发器。

创建一个存储过程ADD_RESIDENT(),并在该过程中执行所有逻辑:插入驻留表(包括记录插入时间的跟踪列,执行插入的帐户等),定义一个游标选择所有未占用的房间FOR UPDATE,获取返回的第一行,与占用者一起更新该行,关闭光标,如果没有找到未占用的房间则引发异常。把你想要的一切都放在这个程序中:调试,审计,记录,等等 - 只是没有COMMIT,没有“其他时候的例外”。

确保面向最终用户的应用程序帐户具有对数据库表的只读访问权限,并且只能通过执行此类存储过程进行更改(即插入居民)。如果您尚未为此角色创建单独的user_account,请暂停并立即执行此操作。

承诺您将发现自己花费更少的时间以这种方式构建应用程序 - 甚至是为您的启发而构建的单个“玩具”应用程序。而且我也保证你会少得多!@#$ - 列表,如果其他任何开发人员都愿意为你的应用程序做出贡献。

答案 1 :(得分:0)

您似乎在select子句中缺少FROM Room。试试这个:

Create OR REPLACE TRIGGER Room_Assign
BEFORE INSERT ON Residents
FOR EACH ROW

BEGIN
FOR Room_Num in 1..MAX(Room_Num) loop
if (Rooms.Occupant IS NULL)
THEN
update Rooms Set Occupant = new.Resid_ID where Occupant IS NULL;
SELECT Rooms.Room_Num INTO Residents.Room_Num FROM Rooms;
Exit;

END IF;
END loop;
IF (new.Resid_ID IS NULL)
 DBMS_OUTPUT.PUT_LINE("There are no vacant rooms.");
END IF;
END;
 /