Skip to main content
Solved

Background job causing mutating table


Forum|alt.badge.img+5

Hi All,

I’m new to writing background jobs so I’m hoping that I’ve just messed something up, and there’s a relatively straightforward solution to my problem. For some background, we’ve found that when attaching a document to project connected PO, that the document is only connected to the PO line:

We would like it to also be connected to the corresponding Project and Activity. 

I initially created a custom event/action to do this:

But this gave me the mutating table error. 

When looking for a way to fix this, I saw several other posts that suggested creating a background job (which I haven’t done before). I tried to piece a background job together by looking at the posts I saw but I’m still getting a mutating table error, so I feel like I’m missing something.

Here’s the code that I’m trying to use:

DECLARE

	--Custom Variables
	var_key_ref varchar2(2000);
	var_project_id varchar2(2000) :=purchase_order_line_part_api.get_project_id(regexp_substr(var_key_ref,'(=)([^=\^]+)(\^)',1, 2, 'i', 2), regexp_substr(var_key_ref,'(=)([^=\^]*)(\^)',1, 1, 'i', 2), regexp_substr(var_key_ref,'(=)([^=\^]+)(\^)',1, 3, 'i', 2));
	var_activity_seq varchar2(2000) :=purchase_order_line_part_api.get_ACTIVITY_SEQ(regexp_substr(var_key_ref,'(=)([^=\^]+)(\^)',1, 2, 'i', 2), regexp_substr(var_key_ref,'(=)([^=\^]*)(\^)',1, 1, 'i', 2), regexp_substr(var_key_ref,'(=)([^=\^]+)(\^)',1, 3, 'i', 2));
	var_key_ref_act	varchar2(2000);
	var_key_ref_proj VARCHAR2(2000);


	--Deferred Call Variables
    attr_         VARCHAR2(32000);
    sql_msg_      VARCHAR2(32000);
    stmt_         VARCHAR2(32000);
    job_id_       NUMBER;
    error_text_   VARCHAR2(2000); 

BEGIN
BEGIN

	select key_ref into var_key_ref from doc_reference_object where doc_class = '&NEW:DOC_CLASS' and doc_no = '&NEW:DOC_NO' and doc_sheet = '&NEW:DOC_SHEET' and doc_rev = '&NEW:DOC_REV' and lu_name like 'PurchaseOrderLine%';
	select purchase_order_line_part_api.get_project_id(regexp_substr(var_key_ref,'(=)([^=\^]+)(\^)',1, 2, 'i', 2), regexp_substr(var_key_ref,'(=)([^=\^]*)(\^)',1, 1, 'i', 2), regexp_substr(var_key_ref,'(=)([^=\^]+)(\^)',1, 3, 'i', 2)) into var_project_id from dual;
	select purchase_order_line_part_api.get_ACTIVITY_SEQ(regexp_substr(var_key_ref,'(=)([^=\^]+)(\^)',1, 2, 'i', 2), regexp_substr(var_key_ref,'(=)([^=\^]*)(\^)',1, 1, 'i', 2), regexp_substr(var_key_ref,'(=)([^=\^]+)(\^)',1, 3, 'i', 2)) into var_activity_seq from dual;																																																	
	select CONCAT(CONCAT('ACTIVITY_SEQ=','&VAR_ACTIVITY_SEQ'),'^') into var_key_ref_act from dual;
	select CONCAT(CONCAT('PROJECT_ID=','&VAR_PROJECT_ID'),'^') into var_key_ref_proj from dual;


--PROJECT																															
Doc_Reference_Object_API.Create_New_Reference('&NEW:DOC_CLASS', '&NEW:DOC_NO', '&NEW:DOC_SHEET', '&NEW:DOC_REV', 'Activity' , CONCAT(CONCAT('ACTIVITY_SEQ=','&VAR_ACTIVITY_SEQ'),'^') , null , '001');

--ACTIVITY
Doc_Reference_Object_API.Create_New_Reference('&NEW:DOC_CLASS', '&NEW:DOC_NO', '&NEW:DOC_SHEET', '&NEW:DOC_REV', 'Project' , CONCAT(CONCAT('PROJECT_ID=','&VAR_PROJECT_ID'),'^') , null , '001');

END;																							


    client_SYS.Clear_Attr(attr_);
    Client_SYS.Add_To_Attr('DOC_CLASS','&NEW:DOC_CLASS', attr_);
    Client_SYS.Add_To_Attr('DOC_NO','&NEW:DOC_NO', attr_);
    Client_SYS.Add_To_Attr('DOC_SHEET','&NEW:DOC_SHEET', attr_);
    Client_SYS.Add_To_Attr('DOC_REV','&NEW:DOC_REV', attr_);
	Client_SYS.Add_To_Attr('LU_NAME','Activity', attr_);
	Client_SYS.Add_To_Attr('KEY_REF','&var_key_ref_act', attr_);



   Transaction_SYS.Deferred_Call(job_id_,'Fnd_Event_Action_API.Action_Executeonlinesql','PARAMETER',attr_,'Add object connections for Project and Activity to PURCHASE_ORD documents.');    
END;

 

And I’m just looking for some pointers to get this cleaned up and working. It’d also be helpful if I knew what I was doing wrong so I can avoid making that mistake again in the future.

Best answer by Mathias Dahl

Okay, found it!

@dsj wrote this nice article about different solutions to this problem:

https://dsj23.me/2021/08/27/tips-to-avoid-mutating-table-error-in-ifs-event-actions/

It’s the second option you are trying and, as I mentioned earlier, you have missed a small part of it :-) 

Look at the stmt_ variable there, what value it is given and how it is used in the later code lines.

Basically, your custom event will put the code to be run in that variable, then ask it to be run in a background job. So you need to convert your code into a string, basically. Will you be able to pull it off?

 

View original
Did this topic help you find an answer to your question?

10 replies

Mathias Dahl
Superhero (Employee)
Forum|alt.badge.img+32
  • Superhero (Employee)
  • 2853 replies
  • May 3, 2022

What is causing the problem is the SELECT done against the same table (doc_reference_object) that the trigger is connected to. Luckily you don’t need that since you have access to all columns in the new record via the &NEW: place holders.

 


Forum|alt.badge.img+5
  • Author
  • Sidekick (Customer)
  • 9 replies
  • May 3, 2022

Thanks for the explanation, Mathias. I just want to make sure I’m tracking with what you’re saying. 

I initially put the SELECT in there because I need to get the KEY_REF from DOC_REFERENCE_OBJECT_TAB table in order to get the Project ID and Activity Sequence Number, and I'm not seeing KEY_REF listed as an available &NEW: field when my event uses DOCUMENT_ISSUE_HISTORY_TAB as it's table.

Would you suggest having the event use DOC_REFERENCE_OBJECT_TAB, rather than DOCUMENT_ISSUE_HISTORY_TAB, instead? I’m just sure how to get KEY_REF without a select statement.


Mathias Dahl
Superhero (Employee)
Forum|alt.badge.img+32
  • Superhero (Employee)
  • 2853 replies
  • May 3, 2022

My bad. I just assumed the trigger was against the doc object reference table since that would be most natural.

So, the mutating error probably comes from the fact that, when you call Doc_Reference_Object_API to create the new connection, that call in turn will insert a new history record in the history table which will make Oracle raise the mutating table error.

Now, there is a way to avoid the mutating table errors, as you have seen. I think you just have misunderstood how it should be done. So, the Transaction_SYS.Deferred_Call is what creates the background job. But from how it looks, you are not running your code in that background job. Your code is running before you create the background, a background job that, I think, does nothing 😁

I'll read up on that other post that explains how to do it, and come back with details.
 


Mathias Dahl
Superhero (Employee)
Forum|alt.badge.img+32
  • Superhero (Employee)
  • 2853 replies
  • Answer
  • May 3, 2022

Okay, found it!

@dsj wrote this nice article about different solutions to this problem:

https://dsj23.me/2021/08/27/tips-to-avoid-mutating-table-error-in-ifs-event-actions/

It’s the second option you are trying and, as I mentioned earlier, you have missed a small part of it :-) 

Look at the stmt_ variable there, what value it is given and how it is used in the later code lines.

Basically, your custom event will put the code to be run in that variable, then ask it to be run in a background job. So you need to convert your code into a string, basically. Will you be able to pull it off?

 


Forum|alt.badge.img+5
  • Author
  • Sidekick (Customer)
  • 9 replies
  • May 3, 2022

Thanks again, Mathias. I was looking at that and I see what you mean about stmt_. You’re thinking something like this?

DECLARE

	--Deferred Call Variables
    attr_         VARCHAR2(32000);
    sql_msg_      VARCHAR2(32000);
    stmt_         VARCHAR2(32000);
    job_id_       NUMBER;
    error_text_   VARCHAR2(2000); 

BEGIN

stmt_ :='

DECLARE

	--Custom Variables
	var_key_ref varchar2(2000);
	var_project_id varchar2(2000);
	var_activity_seq varchar2(2000);

BEGIN

	select key_ref into var_key_ref from doc_reference_object where doc_class = ''&NEW:DOC_CLASS'' and doc_no = ''&NEW:DOC_NO'' and doc_sheet = ''&NEW:DOC_SHEET'' and doc_rev = ''&NEW:DOC_REV'' and lu_name like ''PurchaseOrderLine%'';
	select purchase_order_line_part_api.get_project_id(regexp_substr(var_key_ref,''(=)([^=\^]+)(\^)'',1, 2, ''i'', 2), regexp_substr(var_key_ref,''(=)([^=\^]*)(\^)'',1, 1, ''i'', 2), regexp_substr(var_key_ref,''(=)([^=\^]+)(\^)'',1, 3, ''i'', 2)) into var_project_id from dual;
	select purchase_order_line_part_api.get_ACTIVITY_SEQ(regexp_substr(var_key_ref,''(=)([^=\^]+)(\^)'',1, 2, ''i'', 2), regexp_substr(var_key_ref,''(=)([^=\^]*)(\^)'',1, 1, ''i'', 2), regexp_substr(var_key_ref,''(=)([^=\^]+)(\^)'',1, 3, ''i'', 2)) into var_activity_seq from dual;																																																	


--PROJECT																															
Doc_Reference_Object_API.Create_New_Reference(''&NEW:DOC_CLASS'', ''&NEW:DOC_NO'', ''&NEW:DOC_SHEET'', ''&NEW:DOC_REV'', ''Activity'' , CONCAT(CONCAT(''ACTIVITY_SEQ='',''&VAR_ACTIVITY_SEQ''),''^'') , null , ''001'');

--ACTIVITY
Doc_Reference_Object_API.Create_New_Reference(''&NEW:DOC_CLASS'', ''&NEW:DOC_NO'', ''&NEW:DOC_SHEET'', ''&NEW:DOC_REV'', ''Project'' , CONCAT(CONCAT(''PROJECT_ID='',''&VAR_PROJECT_ID''),''^'') , null , ''001'');

END;';

	sql_msg_ := Message_SYS.Construct('UPD');
   Message_SYS.Add_Attribute(sql_msg_, 'SQL', stmt_);
   Client_SYS.Clear_Attr(attr_);
   Client_SYS.Add_To_Attr('SQL_DATA_', sql_msg_, attr_);
   Client_SYS.Add_To_Attr('MSG_', '', attr_);
   Transaction_SYS.Deferred_Call(job_id_,'Fnd_Event_Action_API.Action_Executeonlinesql','PARAMETER',attr_,'Add object connections for Project and Activity to PURCHASE_ORD documents.');    
END; 

This will run as a background job but it’s returning the following error:

ORA-01403: no data found
ORA-06512: at "IFSAPP.TRANSACTION_SYS", line 2025
ORA-06512: at "IFSAPP.FND_EVENT_ACTION_API", line 2313
ORA-01403: no data found
ORA-06512: at line 12
ORA-06512: at "IFSAPP.FND_EVENT_ACTION_API", line 2309
ORA-06512: at "IFSAPP.FND_EVENT_ACTION_API", line 2318
ORA-06512: at line 1
ORA-06512: at "SYS.DBMS_SQL", line 1721
ORA-06512: at "IFSAPP.TRANSACTION_SYS", line 2015
ORA-06512: at "IFSAPP.TRANSACTION_SYS", line 282
 ORA-06512: at "IFSAPP.TRANSACTION_SYS", line 2025
ORA-06512: at "IFSAPP.FND_EVENT_ACTION_API", line 2313
ORA-06512: at line 12
ORA-06512: at "IFSAPP.FND_EVENT_ACTION_API", line 2309
ORA-06512: at "IFSAPP.FND_EVENT_ACTION_API", line 2318
ORA-06512: at line 1
ORA-06512: at "SYS.DBMS_SQL", line 1721
ORA-06512: at "IFSAPP.TRANSACTION_SYS", line 2015
ORA-06512: at "IFSAPP.TRANSACTION_SYS", line 282
ORA-06512: at "IFSAPP.DEFERRED_JOB_API", line 2080

 


Forum|alt.badge.img+5
  • Author
  • Sidekick (Customer)
  • 9 replies
  • May 3, 2022

I’ve narrowed the error down to this:

select key_ref into var_key_ref from doc_reference_object where doc_class = ''&NEW:DOC_CLASS'' and doc_no = ''&NEW:DOC_NO'' and doc_sheet = ''&NEW:DOC_SHEET'' and doc_rev = ''&NEW:DOC_REV'' and lu_name like ''PurchaseOrderLine%''

If I hard code the key_ref into my code then everything works. I’m just not sure why this is returning no data.

 

Edit: Nevermind. The problem was I did PurchaseOrderLine% when I should’ve just done PurchaseOrder.


Mathias Dahl
Superhero (Employee)
Forum|alt.badge.img+32
  • Superhero (Employee)
  • 2853 replies
  • May 3, 2022

Did you solve it now? If you got the background job to work you might want to consider switching to use doc_reference_object_tab as the table to trigger on. Then you can skip one of the select statements (you will have direct access to the key_ref column) and keep the code simpler.
 


Forum|alt.badge.img+5
  • Author
  • Sidekick (Customer)
  • 9 replies
  • May 4, 2022

Hi Mathias,

 

I did get everything to work as a background job. Thanks so much for your help!

I’m not totally over the finish line yet, though. I’m running into an issue where these snippets of code:

--PROJECT																															
Doc_Reference_Object_API.Create_New_Reference(''&NEW:DOC_CLASS'', ''&NEW:DOC_NO'', ''&NEW:DOC_SHEET'', ''&NEW:DOC_REV'', ''Activity'' , CONCAT(CONCAT(''ACTIVITY_SEQ='',''&VAR_ACTIVITY_SEQ''),''^'') , null , ''001'');

--ACTIVITY
Doc_Reference_Object_API.Create_New_Reference(''&NEW:DOC_CLASS'', ''&NEW:DOC_NO'', ''&NEW:DOC_SHEET'', ''&NEW:DOC_REV'', ''Project'' , CONCAT(CONCAT(''PROJECT_ID='',''&VAR_PROJECT_ID''),''^'') , null , ''001'');

Shows up in Database Background Job as:


-Doc_Reference_Object_API.Create_New_Reference('PURCHASE_ORD', '1725450', '1', '1', 'Activity' , var_activity_key  , null , '001');
-
---ACTIVITY
-Doc_Reference_Object_API.Create_New_Reference('PURCHASE_ORD', '1725450', '1', '1', 'Project' , CONCAT(CONCAT('PROJECT_ID=','&VAR_PROJECT_ID'),'^') , null , '001');
-
-END;
MSG_

Basically, instead of returning the value of the &VAR_ACTIVITY_SEQ and &VAR_PROJECT_ID variables, IFS is returning &VAR_ACTIVITY_SEQ and &VAR_PROJECT_ID as literal values. 


Mathias Dahl
Superhero (Employee)
Forum|alt.badge.img+32
  • Superhero (Employee)
  • 2853 replies
  • May 5, 2022

Good to hear it's progressing! 😃

As for the problem, you can only use the &-syntax for variables you set up in the custom event definition. So, to take an example, for the variable var_activity_seq you should just use it as it is without anything around it.

So, instead of this:

Doc_Reference_Object_API.Create_New_Reference(''&NEW:DOC_CLASS'', ''&NEW:DOC_NO'', ''&NEW:DOC_SHEET'', ''&NEW:DOC_REV'', ''Activity'' , CONCAT(CONCAT(''ACTIVITY_SEQ='',''&VAR_ACTIVITY_SEQ''),''^'') , null , ''001'');

You should use this:

Doc_Reference_Object_API.Create_New_Reference(''&NEW:DOC_CLASS'', ''&NEW:DOC_NO'', ''&NEW:DOC_SHEET'', ''&NEW:DOC_REV'', ''Activity'' , CONCAT(CONCAT(''ACTIVITY_SEQ='',var_activity_seq),''^'') , null , ''001'');

Or even this (I think it's easier to not use the CONCAT function and use the concatenation operator || instead):

Doc_Reference_Object_API.Create_New_Reference(''&NEW:DOC_CLASS'', ''&NEW:DOC_NO'', ''&NEW:DOC_SHEET'', ''&NEW:DOC_REV'', ''Activity'' , ''ACTIVITY_SEQ='' || var_activity_seq || ''^'') , null , ''001'');

I hope I got that right. Did not test it…

 


Mathias Dahl
Superhero (Employee)
Forum|alt.badge.img+32
  • Superhero (Employee)
  • 2853 replies
  • May 13, 2022

@TODDUNCLIFFE 

Did that work out for you?

 


Reply


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings