This document discusses the evolution of user-defined functions (UDFs) in Oracle SQL over multiple Oracle database versions. It shows how UDFs started as PL/SQL functions callable from SQL in earlier versions, which could impact performance. It then demonstrates how newer Oracle database versions allow defining UDFs directly in SQL for improved performance and maintainability when using functions in SQL statements and queries. The document provides examples of different ways to implement and call UDFs across various Oracle versions.
14. SQL> create or replace
2 function my_initcap(p_string varchar2) return varchar2 is
3 l_string varchar2(1000) := p_string;
4 begin
5 if regexp_like(l_string,'(Mac[A-Z]|Mc[A-Z])') then
6 null;
7 elsif l_string like '''%' then
8 null;
9 else
10 l_string := initcap(l_string);
11 if l_string like '_''S%' then
12 null;
13 else
14 l_string := replace(l_string,'''S','''s');
15 end if;
16 end if;
17
18 return l_string;
19 end;
20 /
Function created.
22. SQL> select
2 case
3 when regexp_like(vendor,'(Mac[A-Z]|Mc[A-Z])') then vendor
4 when vendor like '''%' then vendor
5 when initcap(vendor) like '_''S%' then vendor
6 else replace(initcap(vendor),'''S','''s')
7 end ugh
8 from service_provider;
UGH
-------------------------------
Jones
Brown
Smith
McDonald
Johnson's
25. SQL> WITH
2 function my_initcap(p_string varchar2)
3 return varchar2 is
4 l_string varchar2(1000) := p_string;
5 begin
6 if regexp_like(l_string,'(Mac[A-Z]|Mc[A-Z])') then
7 null;
8 elsif l_string like '''%' then
...
17
18 return l_string;
19 end;
20 select my_initcap(vendor)
21 from service_provider;
MY_INITCAP(VENDOR)
-----------------------------------------
Jones
Brown
Smith
McDonald
O'Brien
Johnson's
27. SQL> WITH
2 function is_scottish(p_string varchar2) return boolean is
3 begin
4 return regexp_like(p_string,'(Mac[A-Z]|Mc[A-Z])');
5 end;
6 function my_initcap(p_string varchar2) return varchar2 is
7 l_string varchar2(1000) := p_string;
8 begin
9 if is_scottish(l_string) then
10 null;
11 elsif l_string like '''%' then
12 null;
13 else
14 l_string := initcap(l_string);
15 if l_string like '_''S%' then
16 null;
17 else
18 l_string := replace(l_string,'''S','''s');
19 end if;
20 end if;
21
22 return l_string;
23 end;
24 select my_initcap(surname)
25 from names;
26 /
30. SQL> WITH
2 function my_initcap(p_string varchar2) return varchar2 is
3 l_string varchar2(1000) := p_string;
function my_initcap(p_string varchar2) return varchar2 is
*
ERROR at line 2:
ORA-06553: PLS-103: Encountered the symbol "end-of-file" when
expecting one of the following:
. ( * @ % & = - + ; < / > at in is mod remainder not rem
<an exponent (**)> <> or != or ~= >= <= <> and or like like2
like4 likec between || multiset member submultiset
SQL> begin
2 if regexp_like(l_string,'(Mac[A-Z]|Mc[A-Z])') then
3 null;
4 elsif l_string like '''%' then
5 null;
6 else
7 l_string := initcap(l_string);
37. SQL> insert into CONTRACTS
2 WITH
3 function my_initcap(p_string varchar2)
4 return varchar2 is
5 l_string varchar2(1000) := p_string;
6 begin
...
20 end;
21 select my_initcap(vendor)
22 from service_provider;
23 /
WITH
*
ERROR at line 2:
ORA-32034: unsupported use of WITH clause
38. SQL> insert /*+ WITH_PLSQL */ into CONTRACTS
2 WITH
3 function my_initcap(p_string varchar2)
4 return varchar2 is
5 l_string varchar2(1000) := p_string;
6 begin
...
20 end;
21 select my_initcap(surname)
22 from names;
23 /
5 rows inserted.
40. SQL> with
2 function f return timestamp as
3 begin
4 return systimestamp;
5 end;
6 select f
7 from dual
8 connect by level <= 10;
9 /
F
----------------------------------------
05-JAN-14 08.09.43.969000000 PM
05-JAN-14 08.09.43.970000000 PM
05-JAN-14 08.09.43.970000000 PM
05-JAN-14 08.09.43.971000000 PM
...
44. SQL> with
2 function f return timestamp as
3 begin
4 return systimestamp;
5 end;
6 select ( select f from dual )
7 from dual
8 connect by level <= 10;
9 /
F
----------------------------------------
05-JAN-14 08.11.50.145000000 PM
05-JAN-14 08.11.50.145000000 PM
05-JAN-14 08.11.50.145000000 PM
05-JAN-14 08.11.50.145000000 PM
...
46. SQL> create or replace
2 function F return number is
3 begin
4 return 1;
5 end;
6 /
Function created.
47. SQL> select sum(f)
2 from
3 ( select level from dual
4 connect by level <= 1000 ),
5 ( select level from dual
6 connect by level <= 1000 )
7 ;
SUM(F)
----------
1000000
Elapsed: 00:00:02.04
48. SQL> with
2 function f1 return number is
3 begin
4 return 1;
5 end;
6 select sum(f1)
7 from
8 ( select level from dual
9 connect by level <= 1000 ),
10 ( select level from dual
11 connect by level <= 1000 )
12 /
SUM(F1)
----------
1000000
Elapsed: 00:00:00.52