⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 altind.pkg

📁 OReilly Oracle PL SQL Programming第4版源代码
💻 PKG
字号:
CREATE OR REPLACE PACKAGE ALTIND
IS
   FUNCTION onerow (employee_id_in IN employee.employee_id%TYPE)
      RETURN employee%ROWTYPE;

   FUNCTION onerow (
      last_name_in IN employee.last_name%TYPE,
      usehash IN BOOLEAN := TRUE)
      RETURN employee%ROWTYPE;

   FUNCTION onerow_dbind (last_name_in IN employee.last_name%TYPE)
      RETURN employee%ROWTYPE;

   FUNCTION onerow_dbnoind (last_name_in IN employee.last_name%TYPE)
      RETURN employee%ROWTYPE;

   PROCEDURE loadcache;

   PROCEDURE showhash;

   PROCEDURE trc (
      strt_in IN PLS_INTEGER := 2,   /* NYC 5/99 */
      maxrange_in IN PLS_INTEGER);

   PROCEDURE notrc;

   FUNCTION tracing
      RETURN BOOLEAN;
END;



/
CREATE OR REPLACE PACKAGE BODY ALTIND    
IS
   c_maxrange CONSTANT PLS_INTEGER := POWER (2, 31) - 1;
   g_maxrange PLS_INTEGER := c_maxrange;

   c_strt CONSTANT PLS_INTEGER := 2;
   g_strt PLS_INTEGER := c_strt;

   TYPE tab_tabtype IS TABLE OF employee%ROWTYPE
      INDEX BY BINARY_INTEGER;

   loadtab tab_tabtype;

   TYPE hash_rectype IS RECORD (
   str                           employee.last_name%TYPE,
   key                           employee.employee_id%TYPE
   );

   TYPE hash_tabtype IS TABLE OF hash_rectype
      INDEX BY BINARY_INTEGER;

   hashtab hash_tabtype;
   probeby PLS_INTEGER := 3;
   g_trc BOOLEAN := FALSE;

   PROCEDURE trc (
      strt_in IN PLS_INTEGER := 2,   /* NYC 5/99 */
      maxrange_in IN PLS_INTEGER)
   IS
   BEGIN
      g_trc := TRUE;
      g_maxrange := NVL (maxrange_in, c_maxrange);
      g_strt := NVL (strt_in, c_strt);
   END;

   PROCEDURE notrc
   IS
   BEGIN
      g_trc := FALSE;
      g_maxrange := c_maxrange;
   END;

   FUNCTION tracing
      RETURN BOOLEAN
   IS
   BEGIN
      RETURN g_trc;
   END;

   PROCEDURE probe_ahead (indx IN OUT PLS_INTEGER)
   /* 5/99 NYC enhance to wrap at end. */

   IS
   BEGIN
      IF indx >= c_maxrange - probeby
      THEN
         indx := 1;
      ELSE
         indx := indx + probeby;
      END IF;
   END;

   FUNCTION hashval (str IN VARCHAR2)
      RETURN PLS_INTEGER
   IS
   BEGIN
      RETURN DBMS_UTILITY.get_hash_value (str, g_strt, g_maxrange);
   END;

   PROCEDURE add_to_altind (str_in IN VARCHAR2, key_in IN PLS_INTEGER)
   IS
      end_search BOOLEAN := FALSE;
      v_row PLS_INTEGER := hashval (str_in);
   BEGIN
      IF tracing
      THEN
         do.pl /* do.pkg */ ('Adding key '|| key_in || ' for', str_in);
      END IF;


      /* Resolve hash conflict with linear probe method. */


      LOOP
         IF hashtab.EXISTS (v_row)
         THEN
            IF tracing
            THEN
               do.pl /* do.pkg */ (
                  'Conflict for string '|| str_in || ' occurred at row ',
                  v_row
               );
            END IF;


            /* If this row is in use and it is NOT the same string,
               move to the next row and try again. */


            IF hashtab (v_row).str != str_in
            THEN
               /* Dallas: what about going past the max row? */
               probe_ahead (v_row);   /* NYC 5/99 */
            ELSE

               /* Same string, same row. No action necessary. */

               end_search := TRUE;
            END IF;
         ELSE

            /* Insert a new row in the hash table. */

            IF tracing
            THEN
               do.pl /* do.pkg */ (
                  'Adding '|| str_in || '-'|| key_in || ' '|| ' to row '|| v_row
               );
            END IF;

            hashtab (v_row).str := str_in;
            hashtab (v_row).key := key_in;
            end_search := TRUE;
         END IF;

         EXIT WHEN end_search;
      END LOOP;
   END;

   FUNCTION keyval (str_in IN VARCHAR2)
      RETURN PLS_INTEGER
   IS
      end_search BOOLEAN := FALSE;
      retval PLS_INTEGER := hashval (str_in);
   BEGIN
      IF tracing
      THEN
         do.pl /* do.pkg */ ('Retrieving key for', str_in);
      END IF;

      LOOP
         IF hashtab.EXISTS (retval)
         THEN

            /* If the string matches, we are done. */

            IF hashtab (retval).str = str_in
            THEN
               IF tracing
               THEN
                  do.pl /* do.pkg */ ('Found match at', retval);
               END IF;

               retval := hashtab (retval).key;
               end_search := TRUE;
            ELSE

               /* Try the next row. */

               IF tracing
               THEN
                  do.pl /* do.pkg */ ('Probing next row at', retval + probeby);
               END IF;

               probe_ahead (retval);

            END IF;
         ELSE
            retval := NULL;
            end_search := TRUE;
         END IF;

         EXIT WHEN end_search;
      END LOOP;

      RETURN retval;
   END;

   FUNCTION onerow (employee_id_in IN employee.employee_id%TYPE)
      RETURN employee%ROWTYPE
   IS
   BEGIN
      RETURN loadtab (employee_id_in);
   END;

   FUNCTION onerow (
      last_name_in IN employee.last_name%TYPE,
      usehash IN BOOLEAN := TRUE)
      RETURN employee%ROWTYPE
   IS
      v_employee_id employee.employee_id%TYPE;
      v_row PLS_INTEGER;
   BEGIN
      IF usehash
      THEN
         v_employee_id := keyval (last_name_in);
      ELSE
         v_row := loadtab.FIRST;

         LOOP
            EXIT WHEN v_row IS NULL;

            IF loadtab (v_row).last_name = last_name_in
            THEN
               v_employee_id := v_row;
               EXIT;
            END IF;

            v_row := loadtab.NEXT (v_row);
         END LOOP;
      END IF;

      IF v_employee_id IS NULL
      THEN
         RETURN NULL;
      ELSE
         RETURN onerow (v_employee_id);
      END IF;
   END;

   FUNCTION onerow_dbind (last_name_in IN employee.last_name%TYPE)
      RETURN employee%ROWTYPE
   IS
      CURSOR onerow_cur
      IS
         SELECT *
           FROM employee
          WHERE last_name = last_name_in;

      onerow_rec employee%ROWTYPE;
   BEGIN
      OPEN onerow_cur;
      FETCH onerow_cur INTO onerow_rec;
      CLOSE onerow_cur;
      RETURN onerow_rec;
   END;


   FUNCTION onerow_dbnoind (last_name_in IN employee.last_name%TYPE)
      RETURN employee%ROWTYPE
   IS
      CURSOR onerow_cur
      IS
         SELECT *
           FROM employee
          WHERE RTRIM (last_name) = last_name_in;

      onerow_rec employee%ROWTYPE;
   BEGIN
      OPEN onerow_cur;
      FETCH onerow_cur INTO onerow_rec;
      CLOSE onerow_cur;
      RETURN onerow_rec;
   END;

   PROCEDURE showhash
   IS
      v_row PLS_INTEGER := hashtab.FIRST;
   BEGIN
      LOOP
         EXIT WHEN v_row IS NULL;
         do.pl /* do.pkg */ (
            'Row '||
            v_row ||
            '-Str: '||
            hashtab (v_row).str ||
            '-'||
            'Hash: '||
            hashval (hashtab (v_row).str) ||
            '-'||
            'Key: '||
            hashtab (v_row).key
         );
         v_row := hashtab.NEXT (v_row);
      END LOOP;
   END;

   PROCEDURE loadcache
   IS
   BEGIN
      loadtab.DELETE;
      hashtab.DELETE;

      FOR rec IN ( SELECT *
                     FROM employee)
      LOOP
         loadtab (rec.employee_id) := rec;
         add_to_altind (rec.last_name, rec.employee_id);
      END LOOP;
   END;

BEGIN
   loadcache;
END;
/








/*======================================================================
| Supplement to the third edition of Oracle PL/SQL Programming by Steven
| Feuerstein with Bill Pribyl, Copyright (c) 1997-2002 O'Reilly &
| Associates, Inc. To submit corrections or find more code samples visit
| http://www.oreilly.com/catalog/oraclep3/
*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -