好奇,说我有这个Seeded Function FND_GLOBAL.USER_ID
返回当前登录用户的User_ID,我有一个自定义包(下面)更新了一堆表(表dml和ddl在问题的结尾)。
一个程序只调用FND_GLOBAL.USER_ID
并将其分配给一个局部变量,另一个程序调用{{1}}:
FND_GLOBAL.USER_ID
在单独的会话中,我运行下面的脚本以使用create or replace package call_pkg_var is
procedure call_once (p_trx_no number);
procedure call_multi (p_trx_no number);
end call_pkg_var;
/
create or replace package body call_pkg_var is
procedure call_once (p_trx_no number)
is
l_user_id number := fnd_global.user_id;
begin
update table_a
set user_id = l_user_id
where trx_no = p_trx_no;
update table_b
set user_id = l_user_id
where trx_no = p_trx_no;
update table_c
set user_id = l_user_id
where trx_no = p_trx_no;
end call_once;
procedure call_multi (p_trx_no number)
is
begin
update table_a
set user_id = FND_GLOBAL.USER_ID
where trx_no = p_trx_no;
update table_b
set user_id = FND_GLOBAL.USER_ID
where trx_no = p_trx_no;
update table_c
set user_id = FND_GLOBAL.USER_ID
where trx_no = p_trx_no;
end call_multi;
end call_pkg_var;
/
更新表格:
call_pkg_var.call_once
这个使用set timing on;
begin
for i in 1 .. 10000 loop
call_pkg_var.call_once(i);
end loop;
commit;
end;
:
call_pkg_var.call_multi
结果:
set timing on;
begin
for i in 1 .. 10000 loop
call_pkg_var.call_multi(i);
end loop;
commit;
end;
这是否会以某种方式说多次调用函数比仅将函数分配给变量更好? 如果没有,最好的方法是什么?
表DML和DDL
Run# call_pkg_var.call_once
------- -----------------------
1 00:00:02.248
2 00:00:02.100
3 00:00:02.101
4 00:00:02.069
5 00:00:02.136
6 00:00:02.113
------ -------------
Average 00:00:02.128
Run# call_pkg_var.call_multi
------- -----------------------
1 00:00:02.051
2 00:00:02.047
3 00:00:02.054
4 00:00:02.071
5 00:00:02.054
6 00:00:02.051
------ -------------
Average 00:00:02.055
答案 0 :(得分:0)
我同意brian的观点。总是尝试在构建的函数中使用oracle来获得所需的输出。你可以使用sys_context来获取当前用户,而且我不确定是什么其他方法你正在使用。试着避免sql和pl / sql之间的切换上下文
答案 1 :(得分:0)
大多数人可能不知道的是FND_GLOBAL
是Oracle Corporation作为其Oracle电子商务套件的一部分提供的软件包。
如果您查看该软件包的源代码,您会看到FND_GLOBAL
已经在PL /中缓存了USER_ID
,这是e-BS用户ID而不是Oracle数据库用户ID SQL变量。因此,您的“一次呼叫”和“多次呼叫”的工作量几乎完全相同。
我希望“call multi”仍在进行 little 更多的工作 - 如果你运行了很多测试并评估结果,你就能够检测到它统计学。
但是,如果您使用的是Oracle 12c,我不确定该版本是否删除了PL / SQL优化器只能内联调用同一程序单元中的函数的限制。如果启用PL / SQL警告,如果正在进行任何类型的内联,则应该收到警告。
供参考,以下是您的操作方法:
alter session set plsql_warnings='enable:all';
CREATE OR REPLACE PACKAGE... << your package code >>
show errors; -- Works in SQL*Plus, take your chances with other IDEs.