Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Programming PL SQL.doc
Скачиваний:
2
Добавлен:
01.07.2025
Размер:
5.06 Mб
Скачать

11.6.9 Emulating Alternative Indexes in Collections

Prior to Oracle9i Release 2, you could index associative arrays only by BINARY_INTEGER. This means that if I populate a collection with many rows of data about books and I need to find the row that contains a certain title, I must scan the entire collection. This is slow and cumbersome. Is there a better way? One thing you can consider is building your own alternate index into the contents of your collection. The most effective and efficient way to do this is with the Oracle built-in hashing function, DBMS_UTILITY.GET_HASH_VALUE. This function accepts a string and returns an integer value. Ideally, this value is unique for every different string, but in reality there is no way to guarantee this uniqueness. As a result, you must write "conflict resolution" logic in your code.

Sounds intimidating, doesn't it? It is actually fairly straightforward. However, let me note two things:

  • A full exploration of such algorithms is a bit outside the scope of this book.

  • You don't have to write such an algorithm—I've done it for you already! the altind.pkg file on the O'Reilly site shows you exactly how to write this code. It is designed for the manipulation of employee information, but you can easily adapt it to your own needs.

Here is the basic idea. As you populate your main collection with the information you need to manipulate (several times over, in different directions, etc.), you also hash the alternative index value (such as the name of the employee) and use that hash value as the row number in your index collection. So when you are done with your data load, you have filled two collections. Then, when you need to find a row based on a string (employee name), you hash the name to a number, go to that row, get the row number for the main collection, and then grab the desired data. Figure 11-1 provides a graphical representation of these steps.

Figure 11-1. Populating and accessing a hash index

It is probably best to set up this data in the initialization section of your package, as I show for altind here:

CREATE OR REPLACE PACKAGE BODY altind

IS

... body of package ...

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;

For more details about how to apply this technique in your environment, check out the altind.pkg file.

11.7 Collection Pseudo-Functions

I've been working with Oracle's SQL for more than thirteen years and PL/SQL for more than eight, but my brain has rarely turned as many cartwheels over SQL's semantics as it did when I first contemplated the collection pseudo-functions introduced in Oracle8. These pseudo-functions exist to coerce database tables into acting like collections, and vice versa. Because there are some manipulations that work best when data is in one form versus the other, these functions give application programmers access to a rich and interesting set of structures and operations.

The collection pseudo-functions are not available in PL/SQL proper, only in SQL. You can, however, employ these operators in SQL statements that appear in your PL/ SQL code, and it is extremely useful to understand how and when to do so. We'll see examples in the following sections.

The four collection pseudo-functions are as follows:

THE (now deprecated)

Maps a single column value in a single row into a virtual database table. This pseudo-function allows you to manipulate the elements of a persistent collection.

CAST

Maps a collection of one type to a collection of another type. This can encompass mapping a VARRAY into a nested table.

MULTISET

Maps a database table to a collection. With MULTISET and CAST, you can actually retrieve rows from a database table as a collection-typed column.

TABLE

Maps a collection to a database table. This is the inverse of MULTISET.

Oracle introduced these pseudo-functions in order to manipulate collections that live in the database. They are important to our PL/SQL programs for several reasons, not least of which is that they provide an incredibly efficient way to move data between the database and the application.

Yes, these pseudo-functions can be puzzling. But if you're the kind of person who gets truly excited by arcane code, these SQL extensions introduced in Oracle8 will make you jumping-up-and-down silly.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]