1. 程式人生 > >《Oracle PL/SQL開發指南》學習筆記31——原始碼除錯——函式和過程(第四部分,物件表函式,result_cache子句)

《Oracle PL/SQL開發指南》學習筆記31——原始碼除錯——函式和過程(第四部分,物件表函式,result_cache子句)

 

建立一個物件表函式有三個步驟:

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 行。