The FND_MSG processing integrated in EBS is very convenient. In addition to the convenient pop-up windows and prompt messages in the form, it can also be conveniently borrowed to collect error information when writing PL/SQL packages. And this is based on the session, which is different from the customized log table.
Principle and usage instructions
Image 1 (IBY_UNIQ_ACCOUNT):
Image 2 (AFDICT- DATABASE STATS):
Example code:
DECLARE
x_msg_count NUMBER;
x_msg_data VARCHAR2(3000);
v_msg_index_out NUMBER;
v_data VARCHAR2(1000);
BEGIN
fnd_msg_pub.Initialize;--或者 fnd_message.CLEAR;
fnd_message.set_name('IBY', 'IBY_UNIQ_ACCOUNT'); --设置消息名称
fnd_msg_pub.add; --添加到Global Area
fnd_message.set_name('FND', 'AFDICT- DATABASE STATS'); --设置消息名称
fnd_message.set_token('UPDATES', 'Steven123'); --设置消息内容中变量的值
fnd_message.set_token('INSERTS', 'Steven321'); --设置消息内容中变量的值
fnd_msg_pub.add; --添加到Global Area
--当x_msg_count 为1时,直接输出x_msg_data,否则需要循环输出
fnd_msg_pub.count_and_get(p_encoded => fnd_api.g_false, p_count => x_msg_count, p_data => x_msg_data);
dbms_output.put_line('x_msg_count:' || x_msg_count);
dbms_output.put_line('x_msg_data:' || x_msg_data);
FOR k IN 1 .. x_msg_count
LOOP
fnd_msg_pub.get(p_msg_index => k,
p_encoded => fnd_api.g_false,
p_data => v_data,
p_msg_index_out => v_msg_index_out);
dbms_output.put_line('(' || v_msg_index_out || ')->' || v_data);
END LOOP;
fnd_msg_pub.delete_msg();
END;
Output information:
x_msg_count:2
x_msg_data:
(1)->外部银行帐户已存在
(2)->已更新 Steven123 信息,并已插入 Steven321 信息。
It can be seen from the above that fnd_message.set_name(APPLICATION => , NAME => ); The first parameter of this process is to fill in the application abbreviation, and the second is to fill in the pre-defined error message code.
fnd_message.set_token('UPDATES', 'Steven123') is to replace &XXX in the message definition with the actual value.
Secondary packaging of stored procedures
When outputting, the following stored procedure is generally used to output:
PROCEDURE log_message_list_p IS
l_msg_index NUMBER;
l_msg_data VARCHAR2(2000);
-------------------------------输出消息队列里面的消息-----------------------
BEGIN
IF (fnd_msg_pub.count_msg > 0) THEN
log_p('Error Message Stack :');
log_p('----------------------------------------');
FOR i IN 1 .. fnd_msg_pub.count_msg LOOP
fnd_msg_pub.get(p_msg_index => i,
p_encoded => fnd_api.g_false,
p_data => l_msg_data,
p_msg_index_out => l_msg_index);
log_p(l_msg_data);
END LOOP;
log_p('format_error_stack:' || chr(10) ||
dbms_utility.format_error_stack);
log_p('format_call_stack:' || chr(10) ||
dbms_utility.format_call_stack);
log_p('format_error_backtrace:' || chr(10) ||
dbms_utility.format_error_backtrace);
END IF;
EXCEPTION
WHEN OTHERS THEN
NULL;
END log_message_list_p;
application in request
If it is used in EBS request, it can also be used like this:
PROCEDURE main_p(errbuf OUT VARCHAR2,
retcode OUT VARCHAR2,
p_period_num_from IN VARCHAR2,
p_period_num_to IN VARCHAR2) IS
l_return_status VARCHAR2(30);
l_msg_data VARCHAR2(2000);
l_msg_count NUMBER;
------------------------------调用输出程序------------------
BEGIN
retcode := '0';
--............................
--业务处理逻辑代码XXXXX
--调用标准API
--...........................
EXCEPTION
WHEN fnd_api.g_exc_error THEN
log_message_list_p;
retcode := '1';
fnd_msg_pub.count_and_get(p_encoded => fnd_api.g_false,
p_count => l_msg_count,
p_data => l_msg_data);
IF l_msg_count > 1 THEN
l_msg_data := fnd_msg_pub.get_detail(p_msg_index => fnd_msg_pub.g_first,
p_encoded => fnd_api.g_false);
END IF;
errbuf := l_msg_data;
WHEN fnd_api.g_exc_unexpected_error THEN
log_message_list_p;
retcode := '2';
fnd_msg_pub.count_and_get(p_encoded => fnd_api.g_false,
p_count => l_msg_count,
p_data => l_msg_data);
IF l_msg_count > 1 THEN
l_msg_data := fnd_msg_pub.get_detail(p_msg_index => fnd_msg_pub.g_first,
p_encoded => fnd_api.g_false);
END IF;
errbuf := l_msg_data;
WHEN OTHERS THEN
log_p(dbms_utility.format_error_stack ||
dbms_utility.format_error_backtrace);
fnd_msg_pub.add_exc_msg(p_pkg_name => g_pkg_name,
p_procedure_name => 'MAIN_P',
p_error_text => substrb(SQLERRM, 1, 240));
log_message_list_p;
retcode := '2';
errbuf := SQLERRM;
END main_p;
References
http://blog.itpub.net/25684327/viewspace-694126/
https://imdjkoch.wordpress.com/tag/fnd_message-set_token/
https://docs.oracle.com/cd/E18727_01/doc.121/e12897/T302934T462354.htm