我需要设置一个约束,即用户在一个月内输入5条记录后无法输入任何记录。我是否应该为此编写触发器或程序?否则,我可以设置约束的任何其他方式?
我没有编写触发器,而是选择为约束编写程序,但如何检查程序是否有效?
以下是程序:
CREATE OR REPLACE PROCEDURE InsertReadingCheck
(
newReadNo In Int,
newReadValue In Int,
newReaderID In Int,
newMeterID In Int
)
AS
varRowCount Int;
BEGIN
Select Count(*) INTO varRowCount
From Reading
WHERE ReaderID = newReaderID
AND Trunc(ReadDate,'mm') = Trunc(Sysdate,'mm');
IF (varRowCount >= 5) THEN
BEGIN
DBMS_OUTPUT.PUT_LINE('*************************************************');
DBMS_OUTPUT.PUT_LINE('');
DBMS_OUTPUT.PUT_LINE(' You attempting to enter more than 5 Records ');
DBMS_OUTPUT.PUT_LINE('');
DBMS_OUTPUT.PUT_LINE('*************************************************');
ROLLBACK;
RETURN;
END;
ELSIF (varRowCount < 5) THEN
BEGIN
INSERT INTO Reading
VALUES(seqReadNo.NextVal, sysdate, newReadValue,
newReaderID, newMeterID);
COMMIT;
END;
END IF;
END;
任何人都可以帮我看看
答案 0 :(得分:2)
这是你应该避免放入触发器的事情。特别是ROLLBACK和COMMIT。这似乎非常危险(我甚至不确定它是否可能)。您可能有其他事务要提交以进行回滚,反之亦然。
此外,通过将其置于触发器中, 将会出现以下错误:
ORA-04091:表格XXXX正在变异,触发/功能可能看不到它
There are ways round this但他们过分并且涉及做一些时髦的事情,以便绕过甲骨文坚持你做正确的事情。
这是使用存储过程将数据插入表中的绝佳机会。您可以检查之前之前的当前记录的数量,以执行插入操作,这意味着无需执行ROLLBACK。
答案 1 :(得分:0)
这是一种行为约束。这是一个意见问题,但我会错误地将这种业务逻辑保留在您的数据库之外。我会跟踪谁在记录表中添加了哪些记录,以及在哪些日期/时间。您可以使用SP来获取此信息,但后面的代码应该处理用户是否可以根据返回的数据查看某些链接(或函数)。这是否意味着阻止用户访问他们插入记录的页面,或者给他们只读视图取决于您自己。
答案 2 :(得分:0)
这取决于您的应用程序,如果您的应用程序中已经存在多次插入,那么触发器是更好的选择。
答案 3 :(得分:0)
您可以解决此问题的一种声明方式是遵守所有并发规则,即使用单独的表来跟踪每个用户每月的插入数量:
create table inserts_check (
ReaderID integer not null,
month date not null,
number_of_inserts integer constraint max_number_of_inserts check (number_of_inserts <= 5),
primary key (ReaderID, month)
);
然后在表(或所有表)上创建一个触发器,其插入的上限应为5:
create trigger after insert on <table>
for each row
begin
MERGE INTO inserts_check t
USING (select 5 as ReaderID, trunc(sysdate, 'MM') as month, 1 as number_of_inserts from dual) s
ON (t.ReaderID = s.ReaderID and t.month = s.month)
WHEN MATCHED THEN UPDATE SET t.number_of_inserts = t.number_of_inserts + 1
WHEN NOT MATCHED THEN INSERT (ReaderID, month, number_of_inserts)
VALUES (s.ReaderID, s.month, s.number_of_inserts);
end;
一旦用户进行了5次插入,约束max_number_of_inserts
将失败。