I would like my table to sequence its "order by" column based on it's TEMPLATE\_ID.
I would like this to happen on insert (via an insert trigger, probably).
For example, if I run the following inserts, I should get the following table values.

```
INSERT INTO TEMPLATE_ATTRIBUTES (ID, TEMPLATE_ID) VALUES (1, 1)
INSERT INTO TEMPLATE_ATTRIBUTES (ID, TEMPLATE_ID) VALUES (2, 1)
INSERT INTO TEMPLATE_ATTRIBUTES (ID, TEMPLATE_ID) VALUES (3, 1)
INSERT INTO TEMPLATE_ATTRIBUTES (ID, TEMPLATE_ID) VALUES (4, 2)
INSERT INTO TEMPLATE_ATTRIBUTES (ID, TEMPLATE_ID) VALUES (5, 2)
INSERT INTO TEMPLATE_ATTRIBUTES (ID, TEMPLATE_ID) VALUES (6, 2)
INSERT INTO TEMPLATE_ATTRIBUTES (ID, TEMPLATE_ID) VALUES (7, 2)
INSERT INTO TEMPLATE_ATTRIBUTES (ID, TEMPLATE_ID) VALUES (8, 3)

ID TEMPLATE_ID ORDER_BY
 1           1        1
 2           1        2
 3           1        3
 4           2        1
 5           2        2
 6           2        3
 7           2        4
 8           3        1

```

I first tried to create this trigger, but it gives me an error when I insert.

```
create or replace
trigger TEMPLATE_ATTRIBUTES_AF_INS_TRIG
   after insert on TEMPLATE_ATTRIBUTES
   for each row
begin
    if :NEW.ORDER_BY is null then
       update TEMPLATE_ATTRIBUTES
       set ORDER_BY = (select coalesce(MAX(ta.ORDER_BY), 0) + 1 from TEMPLATE_ATTRIBUTES ta where ta.TEMPLATE_ID = :NEW.TEMPLATE_ID)
       where ID = :NEW.ID;
    end if;
end;

```

The error it gives me is: "table TEMPLATE\_ATTRIBUTES is mutating, trigger/function may not see it"

So I need a different way to build this trigger. And I also need it to "thread safe" so that if these two inserts occur on different sessions at the same time, then the resulting records will still get different "ORDER\_BY" values:

```
INSERT INTO TEMPLATE_ATTRIBUTES (ID, TEMPLATE_ID) VALUES (1, 1)
INSERT INTO TEMPLATE_ATTRIBUTES (ID, TEMPLATE_ID) VALUES (2, 1)

```

Edit:

I tried the common work around for the "table is mutating, trigger/function may not see it" and the work around "worked" but it was not "thread safe." I tried to add locking but it gave me another error on insert

```
create or replace package state_pkg
as 
  type ridArray is table of rowid index by binary_integer; 
  newRows ridArray;
  empty   ridArray; 
end;

create or replace trigger TEMPLATE_ATTRIBUTES_ORDER_BY_TB4 
before insert on TEMPLATE_ATTRIBUTES
begin
  state_pkg.newRows := state_pkg.empty; 
end;

create or replace trigger TEMPLATE_ATTRIBUTES_ORDER_BY_TAF1
after insert on TEMPLATE_ATTRIBUTES for each row 
begin
  if :NEW.ORDER_BY is null then
    state_pkg.newRows( state_pkg.newRows.count+1 ) := :new.rowid;
  end if;
end;

create or replace trigger TEMPLATE_ATTRIBUTES_ORDER_BY_TAF2
after insert on TEMPLATE_ATTRIBUTES
declare
  v_request     number;
  v_lockhandle varchar2(200);
begin
  dbms_lock.allocate_unique('TEMPLATE_ATTRIBUTES_ORDER_BY_lock', v_lockhandle);
  while v_request <> 0 loop
    v_request:= dbms_lock.request(v_lockhandle, dbms_lock.x_mode);
  end loop;
  begin
    for i in 1 .. state_pkg.newRows.count loop
      update TEMPLATE_ATTRIBUTES
      set ORDER_BY = (select coalesce(MAX(q.ORDER_BY), 0) + 1 from TEMPLATE_ATTRIBUTES q where q.TEMPLATE_ID = (select q2.TEMPLATE_ID from TEMPLATE_ATTRIBUTES q2 where q2.rowid = state_pkg.newRows(i)))
      where rowid = state_pkg.newRows(i);
    end loop;
    v_request:= dbms_lock.release(v_lockhandle);
  EXCEPTION WHEN OTHERS THEN 
    v_request:= dbms_lock.release(v_lockhandle);
    raise;
  end;
end;

```

This gives me:

ORA-04092: cannot COMMIT in a trigger ORA-06512: at "SYS.DBMS\_LOCK", line 250 ORA-06512: at "TEMPLATE\_ATTRIBUTES\_ORDER\_BY\_TAF2", line 5 ORA-04088: error during execution of trigger 'TEMPLATE\_ATTRIBUTES\_ORDER\_BY\_TAF2' ORA-06512

Edit 2:
The ORDER\_BY column must be an updateable column.
ID actually uses a sequence and before insert trigger to set its values. I thought I was simplifying my question when I included it in the insert examples, but that was incorrect. ORDER\_BY's initial value is not really related to ID, but rather to what order the records are inserted. But ID is sequenced so you can use that if it helps.