77 lines
2.1 KiB
SQL
77 lines
2.1 KiB
SQL
-- Let's create a generic class with one method to be used as an interface:
|
|
create or replace
|
|
TYPE callback AS OBJECT (
|
|
-- A class needs at least one member even though we don't use it
|
|
-- There's no generic OBJECT type, so let's call it NUMBER
|
|
dummy NUMBER,
|
|
-- Here's our function, and since PL/SQL doesn't have generics,
|
|
-- let's use type NUMBER for our params
|
|
MEMBER FUNCTION exec(n number) RETURN number
|
|
) NOT FINAL not instantiable;
|
|
/
|
|
|
|
-- Now let's inherit from that, defining a class with one method. We'll have ours square a number.
|
|
-- We can pass this class into any function that takes type callback:
|
|
CREATE OR REPLACE TYPE CB_SQUARE under callback (
|
|
OVERRIDING MEMBER FUNCTION exec(n NUMBER) RETURN NUMBER
|
|
)
|
|
/
|
|
CREATE OR REPLACE
|
|
TYPE BODY CB_SQUARE AS
|
|
OVERRIDING MEMBER FUNCTION exec(n NUMBER) RETURN NUMBER IS
|
|
BEGIN
|
|
RETURN n * n;
|
|
END exec;
|
|
END;
|
|
/
|
|
|
|
-- And a package to hold our test
|
|
CREATE OR REPLACE
|
|
PACKAGE PKG_CALLBACK AS
|
|
myCallback cb_square;
|
|
TYPE intTable IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
|
|
ints intTable;
|
|
i PLS_INTEGER;
|
|
|
|
procedure test_callback;
|
|
END PKG_CALLBACK;
|
|
/
|
|
|
|
CREATE OR REPLACE PACKAGE BODY PKG_CALLBACK AS
|
|
-- Our generic mapping function that takes a "method" and a collection
|
|
-- Note that it takes the generic callback type
|
|
-- that doesn't know anything about squaring
|
|
procedure do_callback(myCallback IN callback, ints IN OUT intTable) IS
|
|
i PLS_INTEGER;
|
|
myInt NUMBER;
|
|
begin
|
|
for i in 1 .. ints.count loop
|
|
myInt := ints(i);
|
|
-- PL/SQL call's the child's method
|
|
ints(i) := myCallback.exec(myInt);
|
|
END LOOP;
|
|
end do_callback;
|
|
|
|
procedure test_callback IS
|
|
BEGIN
|
|
myCallback := cb_square(null);
|
|
FOR i IN 1..5 LOOP
|
|
ints(i) := i;
|
|
END LOOP;
|
|
|
|
do_callback(myCallback, ints);
|
|
|
|
i := ints.FIRST;
|
|
WHILE i IS NOT NULL LOOP
|
|
DBMS_OUTPUT.put_line(ints(i));
|
|
i := ints.next(i);
|
|
END LOOP;
|
|
END test_callback;
|
|
END PKG_CALLBACK;
|
|
/
|
|
|
|
BEGIN
|
|
PKG_CALLBACK.TEST_CALLBACK();
|
|
END;
|
|
/
|