任何人都可以解释Oracle中函数和过程之间的主要区别是什么?如果我能用功能做所有事情,为什么我必须使用程序?
我听说主要区别在于性能,'程序比功能更快'。但没有任何细节。
提前致谢。
答案 0 :(得分:44)
区别在于 - 函数必须按默认定义返回值(任何类型),而在过程中,您需要使用OUT
或IN OUT
参数等参数来获取结果。您可以在普通SQL
中使用函数,因为您无法在SQL
语句中使用过程。
功能和程序之间的一些差异
函数总是使用return语句返回一个值,而一个过程可能会通过参数返回一个或多个值,或者根本不会返回。虽然OUT
参数仍然可以在函数中使用,不建议也不存在可能需要这样做的情况。使用OUT
参数限制函数在SQL语句中使用。
函数可用于典型的SQL语句,如SELECT
,INSERT
,UPDATE
,DELETE
,MERGE
,而程序不能
函数通常用于计算,其中过程通常用于执行业务逻辑。
Oracle提供了创建“Function Based Indexes”的功能,以提高后续SQL语句的性能。这适用于对查询的where子句中的索引列执行函数时。
答案 1 :(得分:13)
程序和功能之间几乎没有性能差异。
在极少数情况下:
IN OUT
参数比函数返回更快。IN OUT
参数比函数返回慢。测试代码
--Run one of these to set optimization level:
--alter session set plsql_optimize_level=0;
--alter session set plsql_optimize_level=1;
--alter session set plsql_optimize_level=2;
--alter session set plsql_optimize_level=3;
--Run this to compare times. Move the comment to enable the procedure or the function.
declare
v_result varchar2(4000);
procedure test_procedure(p_result in out varchar2) is
begin
p_result := '0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789';
end;
function test_function return varchar2 is
begin
return '0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789';
end;
begin
for i in 1 .. 10000000 loop
--Comment out one of these lines to change the test.
--test_procedure(v_result);
v_result := test_function;
end loop;
end;
/
<强>结果
Inlining enabled: PLSQL_OPTIMIZE_LEVEL = 2 (default) or 3
Function run time in seconds: 2.839, 2.933, 2.979
Procedure run time in seconds: 1.685, 1.700, 1.762
Inlining disabled: PLSQL_OPTIMIZE_LEVEL = 0 or 1
Function run time in seconds: 5.164, 4.967, 5.632
Procedure run time in seconds: 6.1, 6.006, 6.037
上述代码很简单,可能还需要进行其他优化。但是我在生产代码中看到了类似的结果。
为什么差异无关紧要
不要看上面的测试,并认为“程序的运行速度是函数的两倍!”。是的,函数的开销几乎是过程开销的两倍。但无论哪种方式,开销都无关紧要。
数据库性能的关键是在SQL语句中批量执行尽可能多的工作。如果一个程序每秒调用一次函数或程序一千万次,那么该程序就会出现严重的设计问题。
答案 2 :(得分:9)
国家变化与非国家变化
在Romo Daneghyan's answer之上,我总是把差异视为他们在程序状态下的行为。也就是说,概念上,
也就是说,如果你调用了一个名为generateId(...)
的函数,你会期望它只进行一些计算并返回一个值。但是调用过程generateId ...
,您可能希望它在某些表中更改值。
当然,在Oracle以及许多语言中似乎都不适用,并且没有强制执行,所以也许只是我。
答案 3 :(得分:2)
程序可能会或可能不会返回值,但函数会返回值。
程序使用参数returnvalue目的但函数returnstatment提供。
答案 4 :(得分:1)
这是一个很大的问题,据我所知,尚未真正得到回答。问题不是“函数和过程之间有什么区别?”相反,它是“当我可以使用函数执行相同的操作时,为什么要使用过程?”
我认为真正的答案是“这只是约定。” 并且按照约定,这是其他开发人员习惯并期望的,因此您应该遵循约定。但是没有功能上的原因将子程序作为函数编写为程序。一个例外可能是存在多个OUT
参数时。
Steven Feuerstein在他的6th edition of Oracle PL/SQL Programming中建议您为过程保留OUT
和IN OUT
参数,并且仅通过RETURN子句返回函数中的信息(第613页)。但同样,这样做的原因是惯例。开发人员不希望函数具有OUT
参数。
我写了一个longish post here,主张您仅应在函数无法完成工作时使用过程。我个人更喜欢函数,并希望约定默认使用函数,但是我认为更好的做法是接受我无法更改的内容并屈服于实际约定,而不是我希望的约定
答案 5 :(得分:-2)
我认为主要区别在于:
函数不能包含DML Statemnt,而程序可以。 例如像Update和Insert。
如果我错了纠正我
答案 6 :(得分:-5)
据我所知,Store程序编译一次,可以一次又一次地调用,而无需再次编译。但每次调用时都会编译函数。因此,存储过程提高了性能而非功能。