Hello everybody,
I am not experienced in writing table triggers and I'm stuck with something I don't really understand.
I have a table which keeps track of treatments patients receive. It has a composite primary key pt_id + treatment_number. The treatments should be numbered sequentially depending on the dates they take place. However they don't necessarily come for data entry in their natural order that's why I need to re-number them at insert stage.
Here is the trigger:
And here is the function which is supposed to to the job:
The function works when called from a regular test procedure, but when I insert a record into the table and the trigger fires I get a return code 1, meaning it fails at the first opening of the cursor and as a result it doesn't renumber the records.
Any idea how to fix this?
Thank you in advance,
Alex
I am not experienced in writing table triggers and I'm stuck with something I don't really understand.
I have a table which keeps track of treatments patients receive. It has a composite primary key pt_id + treatment_number. The treatments should be numbered sequentially depending on the dates they take place. However they don't necessarily come for data entry in their natural order that's why I need to re-number them at insert stage.
Here is the trigger:
Code:
CREATE OR REPLACE TRIGGER trg_trt
AFTER INSERT
ON tbl_treatment
FOR EACH ROW
DECLARE
i integer;
BEGIN
i := PKG_TRG_PRC.i_reorder_trt_no(:NEW.pt_id);
dbms_output.put_line('i_err = ' || i);
END trg_trt;
And here is the function which is supposed to to the job:
Code:
FUNCTION i_reorder_trt_no(in_pt_id IN INTEGER)
RETURN INTEGER AS
i_row_no INTEGER;
i_position INTEGER;
CURSOR crs_trt IS SELECT treatment_number, DT_CRT_DATE_FROMPARTS(year,mon,day) AS dt_trt
FROM tbl_Treatment
WHERE pt_id = in_pt_id
ORDER BY dt_trt
FOR UPDATE OF treatment_number;
row_crs_trt crs_trt%ROWTYPE;
BEGIN
i_position := 1;
--first step - assign large numbers beyond possible limit
--to avoid PK violation
OPEN crs_trt;
LOOP
FETCH crs_trt INTO row_crs_trt; -- retrieve a row from table
EXIT WHEN crs_trt%NOTFOUND;
UPDATE tbl_treatment
SET treatment_number = treatment_number + 50
WHERE CURRENT of crs_trt;
END LOOP;
CLOSE crs_trt;
i_position := 2;
--Re-open cursor - second step: As records in cursor set are ordered by
--dt_trt - fetch trt records one by one and apply 1,2,3.. sequence
OPEN crs_trt;
i_row_no := 1;
LOOP
FETCH crs_trt INTO row_crs_trt; -- retrieve a row from table
EXIT WHEN crs_trt%NOTFOUND;
UPDATE tbl_treatment
SET treatment_number = i_row_no
WHERE CURRENT of crs_trt;
i_row_no := i_row_no + 1;
END LOOP;
CLOSE crs_trt;
COMMIT;
RETURN 0;
EXCEPTION
WHEN others THEN
CASE i_position
WHEN 1 THEN
RETURN 1;
WHEN 2 THEN
RETURN 2;
ELSE
RETURN 10;
END CASE;
ROLLBACK;
END i_reorder_trt_no;
The function works when called from a regular test procedure, but when I insert a record into the table and the trigger fires I get a return code 1, meaning it fails at the first opening of the cursor and as a result it doesn't renumber the records.
Any idea how to fix this?
Thank you in advance,
Alex