0

我有一个现有的表postn_matrix,其中包含员工列表和他们的人数。在组织中的职位。

每当添加或删除用户的位置时,相应的计数都会通过此触发器反映在表中(VIA UPDATE)

现在,如果有一个新用户,他将没有条目postn_matrix,所以我必须为他/她插入一条新记录(VIA INSERT)。这需要从 BASE TABLE 中引入。

更新似乎工作正常,但我无法将新用户引入表中。

我一直在尝试用光标处理这种情况。但它还没有任何帮助。我希望一些专家可以向我展示光明.. :)。除了使用光标之外的任何其他建议将不胜感激

CREATE OR REPLACE TRIGGER TRIG1
BEFORE INSERT OR DELETE ON (BASETABLE)
FOR EACH ROW
DECLARE
  cursor c1 is
  select person_id 
  from postn_matrix;

  v_temp varchar2(15);
BEGIN
  IF INSERTING THEN
    open c1;    
    LOOP
      fetch c1 into v_temp;

      if v_temp!=:new.person_id THEN
        insert into POSTN_MATRIX (PERSON_ID)
        VALUES (:new.PERSON_ID);
      else
        UPDATE POSTN_MATRIX
        //this is working fine ;

      END IF;
    end loop;
    close c1;

END
/
4

1 回答 1

4

pstn_matrix由于循环(缺少退出子句-希望您刚刚丢失了将其转换为问题),您将尝试为游标返回的每条记录插入一条记录,无论:new.person_id是否有任何匹配; 如果有匹配,你也会做update. 这可能不是您想要的,并且您可能会遇到约束违规等情况。您也没有设置您的计数器字段 - 如果该字段不可为空,则将出错。但是你还没有说你得到了什么错误,如果有的话。

如果您必须通过触发器执行此操作,那么您可以检查新人是否有一行:

DECLARE
  v_temp postn_matrix.person_id%TYPE;
BEGIN
  IF INSERTING THEN
    select max(person_id) into v_temp
    from postn_matrix
    where person_id = :new.person_id;

    if v_temp is null then
      -- no record found, so insert one
      insert into postn_matrix (person_id, position_count)
      values (:new.person_id, 1);
    else
      -- record exists, so update
      update postn_matrix ...
    end if;
  ...

...或使用merge.

但我不喜欢这个模型,而且你正在设置潜在的数据差异与对基表的并发修改。试图保持这样的计数并不一定像看起来那么简单。

我通常更愿意将此作为视图,它始终是最新的,并且不需要使事情复杂化的触发器:

create view postn_matrix as
  select person_id, count(*)
  from basetable
  group by person_id;

当然,我可能会误解或过度简化您的基表的功能和您的需求postn_matrix。即使作为一种观点,它似乎也有点微不足道。例如,如果您有单独personperson_position表格,那么您可以添加一个外部联接来查看没有职位的人:

create view postn_matrix as
  select p.person_id, count(pp.position_id)
  from person p
  left join person_position pp on pp.person_id = p.person_id
  group by p.person_id;
于 2012-07-20T13:43:59.007 回答