0

正在开发一个应用程序,可以帮助人们在那里计划日程。

假设我有一个名为“Plan_Table”的表,其中有类似的列

id,user_name, timestamp,place,event,plan_number.

对于每一天,一个人可以根据他的活动插入许多记录。我希望由触发器填充“plan_number”列。假设用户一次(批量)插入五条记录。我希望将 plan_number 字段插入为

plan_1
plan_1
plan_1
plan_1
plan_1

如果他想出另一个计划..并且插入很少,这次说 3...我希望将 plan_number 字段插入为

plan_2
plan_2
plan_2

如何使用触发器和序列来实现这一点?

提前致谢。

4

4 回答 4

1
var_plan_number number := 0;
begin 
if :new.plan_number is null then
 select max(plan_number) into var_plan_number from plan_table where timestamp < CURRENT_TIMESTAMP - 5 --*some_treshold - ie 5 seconds* 
 and timestamp > CURRENT_TIMESTAMP and timestamp > trunc(sysdate) and user_name = :new.user_name;
 --idea is to select max plan_number for current day and increment it by 1
 --treshold should be set to time, your script is able to process batch records

 var_plan_number := var_plan_number + 1;    
 :new.plan_number := var_plan_number;
end if;

这应该够了吧...

请将此视为伪代码,您的触发器应该是什么样子。不需要序列。

于 2013-06-19T11:56:14.313 回答
1

问题在于“一次(批量)”的定义。当一批结束和新一批开始时,很难告诉触发器。包变量是可能的,但最有能力的地方是您的应用程序。

我会创建一个序列来生成 id,但在您的应用程序中获取 id 并将它们直接提供给 INSERT 语句:

CREATE SEQUENCE myids;
CREATE TABLE plan_table(id int, user_name varchar2(30), mytimestamp, ...); 

在您的代码中:

SELECT myids.nextval INTO myplanid FROM DUAL;
INSERT INTO plan_table(myplanid, myuser_name, SYSTIMESTAMP, place1 ...);
INSERT INTO plan_table(myplanid, myuser_name, SYSTIMESTAMP, place2 ...);
INSERT INTO plan_table(myplanid, myuser_name, SYSTIMESTAMP, place3 ...); 
COMMIT;
于 2013-06-19T11:56:52.693 回答
1

我认为您可以将该表的 before 语句级触发器与全局包变量结合使用,然后在该表的行级触发器中使用它们。希望它能让您对上述逻辑有所了解

于 2013-06-19T11:30:05.903 回答
0

感谢您为我提供的答案。你真的让我从纯粹的数据库角度思考。作为一名 Web 应用程序开发人员,我认为使用序列/触发器来帮助我解决这个问题是一种更好的方法。但是,我从应用程序本身的业务逻辑中找到了解决方案。

我正在使用 Hibernate ORM 来管理数据库表。因此,我使用以下代码提取了计划编号的最大值。

Session session = getSessionFactory().openSession();
    session.beginTransaction();
    Criteria criteria = session.createCriteria(Mwwp_Plan.class).setProjection(Projections.max("plan_number"));
    Integer maxPlanNumber = (Integer) criteria.uniqueResult(); 
    session.getTransaction().commit();
    System.out.println(maxPlanNumber);
    if(maxPlanNumber==null)
    {
        System.out.println("maxPlanNumber is null");
        maxPlanNumber = 0;
    }
    else
    {

    }
    System.out.println("maxPlanNumber:"+maxPlanNumber);
    return maxPlanNumber;

这是我的应用程序用来获取 max(plan_number) 的函数内部。如果表中没有plan_number。它将默认为 1。

注意:Mwwp_Plan 是我在应用程序中使用的表的名称。

因此,我实现了我想要的。

谢谢你的帮助。

于 2013-06-19T16:18:08.263 回答