创建一个对象表函数有三个步骤:
1. 定义记录结构为对象类型
2. 定义集合
3. 定义一个函数来展示如何从PL/SQL上下文向SQL上下文返回集合
1. 创建基本的SQL用户自定义类型(UDT)
注意:发现竟然不能使用distinct关键字,这个局限怎么破?
SQL> ed
已写入 file afiedt.buf
1 /* Formatted on 2018/12/4 23:05:01 (QP5 v5.256.13226.35538) */
2 CREATE OR REPLACE FUNCTION get_full_titles (pv_title VARCHAR2)
3 RETURN TITLE_TABLE
4 IS
5 -- Declare a variable that uses the record structure.
6 lv_counter PLS_INTEGER := 1;
7 -- Declare a variable that uses the record structure.
8 lv_title_table TITLE_TABLE := title_table ();
9 -- Declare dynamic cursor structure.
10 CURSOR c (cv_search VARCHAR2)
11 IS
12 SELECT item_title, item_subtitle
13 FROM item
14 WHERE REGEXP_LIKE (item_title, '^.*' || cv_search || '.*', 'i')
15 AND item_type = (SELECT common_lookup_id
16 FROM common_lookup
17 WHERE common_lookup_type = 'DVD_WIDE_SCREEN')
18 ORDER BY item_release_date;
19 BEGIN
20 -- Open the cursor and map results to collection.
21 FOR i IN c (pv_title)
22 LOOP
23 lv_title_table.EXTEND; -- Extends memory.
24 /* The assignment pattern for a SQL Collection is
25 incompatible with the cursor return type, and you
26 must construct an instance of the object type
27 before assigning it to collection. */
28 lv_title_table (lv_counter) :=
29 title_structure (i.item_title, i.item_subtitle);
30 lv_counter := lv_counter + 1; -- Increment counter.
31 END LOOP;
32 RETURN lv_title_table;
33* END;
34 /
函数已创建。
SQL> select title from table (get_full_titles('harry'));
TITLE
------------------------------------------------------------
Harry Potter and the Sorcer's Stone
Harry Potter and the Chamber of Secrets
Harry Potter and the Prisoner of Azkaban
Harry Potter and the Chamber of Secrets
Harry Potter and the Goblet of Fire
Harry Potter and the Order of the Phoenix
已选择 6 行。
2. RESULT_CACHE子句
首次接触,学习一下:
The RESULT_CACHE clause was new in Oracle Database 11g. Oracle Database 12c extends the behaviors of result cache functions to work with invoker rights programs. A result cache function stores the function name, the call parameters, the results, and the CURRENT_USER value in the SGA. Oracle Database 12c adds the CURRENT_USER value to the stored results. This is how Oracle Database 12c maintains different result sets for different callers of the same function. The RESULT_CACHE clause instructs the PL/SQL engine to check the result cache for function calls with matching actual parameters. A matching function call also stores the result, and the cache returns the result and skips rerunning the function. This means the function only runs when new parameters are sent to it. The prototype for the RESULT_CACHE clause has an optional RELIES_ON clause. The RELIES_ON clause is critical because it ensures any change to the underlying table invalidates the result cache. This also means any DML transactions that would change result sets. The RELIES_ON clause ensures that the cache is dynamic, representing the current result set. You can list any number of dependent tables in the RELIES_ON clause, and they’re listed as comma delimited names. The next example depends on the downloadable code from the publisher’s website. You can find a description of the code in the Introduction. Also, this example builds upon the discussion of table collections in Chapter 6. This statement lets you build a collection of VARCHAR2 values:
示例:
SQL> CREATE OR REPLACE TYPE strings AS TABLE OF VARCHAR2(60);
2 /
类型已创建。
SQL>
SQL> CREATE OR REPLACE FUNCTION get_title
2 ( partial_title VARCHAR2 ) RETURN STRINGS
3 RESULT_CACHE RELIES_ON(item) IS
4 -- Declare a collection control variable and collection variable.
5 counter NUMBER := 1;
6 return_value STRINGS := strings();
7
8 -- Define a parameterized cursor.
9 CURSOR get_title
10 ( partial_title VARCHAR2 ) IS
11 SELECT item_title
12 FROM item
13 WHERE UPPER(item_title) LIKE '%'||UPPER(partial_title)||'%';
14 BEGIN
15 -- Read the data and write it to the collection in a cursor FOR loop.
16 FOR i IN get_title(partial_title) LOOP
17 return_value.EXTEND;
18 return_value(counter) := i.item_title;
19 counter := counter + 1;
20 END LOOP;
21 RETURN return_value;
22 END get_title;
23 /
函数已创建。
SQL> DECLARE
2 list STRINGS;
3 BEGIN
4 list := get_title('Harry');
5 FOR i IN 1..list.LAST LOOP
6 dbms_output.put_line('list('||i||') : ['||list(i)||']');
7 END LOOP;
8 END;
9 /
PL/SQL 过程已成功完成。
SQL> set serveroutput on
SQL> /
list(1) : [Harry Potter: Goblet of Fire]
list(2) : [Harry Potter: Goblet of Fire]
list(3) : [Harry Potter: Goblet of Fire]
list(4) : [Harry Potter and the Sorcer's Stone]
list(5) : [Harry Potter and the Sorcer's Stone]
list(6) : [Harry Potter and the Chamber of Secrets]
list(7) : [Harry Potter and the Chamber of Secrets]
list(8) : [Harry Potter and the Prisoner of Azkaban]
list(9) : [Harry Potter and the Prisoner of Azkaban]
list(10) : [Harry Potter and the Chamber of Secrets]
list(11) : [Harry Potter and the Goblet of Fire]
list(12) : [Harry Potter and the Goblet of Fire]
list(13) : [Harry Potter and the Goblet of Fire]
list(14) : [Harry Potter and the Order of the Phoenix]
PL/SQL 过程已成功完成。
SQL> select column_value from table(get_title('harry'));
COLUMN_VALUE
------------------------------------------------------------
Harry Potter: Goblet of Fire
Harry Potter: Goblet of Fire
Harry Potter: Goblet of Fire
Harry Potter and the Sorcer's Stone
Harry Potter and the Sorcer's Stone
Harry Potter and the Chamber of Secrets
Harry Potter and the Chamber of Secrets
Harry Potter and the Prisoner of Azkaban
Harry Potter and the Prisoner of Azkaban
Harry Potter and the Chamber of Secrets
Harry Potter and the Goblet of Fire
Harry Potter and the Goblet of Fire
Harry Potter and the Goblet of Fire
Harry Potter and the Order of the Phoenix
已选择 14 行。