Delphi 3. Библиотека программиста

       

Использование сохраненных процедур


Сохраненные процедуры (stored procedures) напоминают SQL с добавлением условных операторов и циклов. На языке InterBase можно написать так называемые процедуры выборки (select procedures), которые аналогично SQL-запросам возвращают некоторое количество записей из набора. С помощью процедурного языка можно перебрать записи, входящие в набор (полученный с помощью запроса или другой, вложенной процедуры выборки), и выполнить с ними необходимые действия. Пример, написанный на командном языке InterBase, приведен в листинге13.7 (нумерация строк используется в последующих комментариях).

Листинг 13.7. Процедуры выборки в InterBase

1. CREATE PROCEDURE GETCHILDREN (STARTING_ITEM_ID SMALLINT, THISLEVEL SMALLINT) 2. RETURNS(ITEM_ID SMALLINT, DESCRIPTION CHAR(30), ITEMLEVEL SMALLINT) AS 3. BEGIN 4. FOR 5. SELECT T1.ITEM_IDM T1.DESCRIPTION 6. FROM ITEMS T1 7. WHERE T1.PARENT_ID = :STARTING_ITEM_ID 8. INTO :ITEM_ID, :DESCRIPTION 9. DO BEGIN 10. ITEMLEVEL = THISLEVEL + 1; 11. SUSPEND; 12. FOR 13. SELECT T1.ITEM_ID, T1.DESCRIPTION, T1.ITEMLEVEL 14. FROM GETCHILDREN(:ITEM_ID, :ITEMLEVEL) T1 15. INTO :ITEM_ID, :DESCRIPTION, :ITEMLEVEL 16. DO BEGIN 17. SUSPEND; 18. END 19. END 20. END;

Подобные итерации идеально подходят для просмотра иерархических данных в обоих направлениях, потому что сохраненные процедуры рекурсивны. Такую процедуру можно вызывать из нее самой, чтобы определить детей текущего объекта, затем получить их детей и т. д. Вместо того чтобы сразу получить все записи одного поколения и переходить к следующему, при этой стратегии мы сначала определяем первого потомка объекта, затем — его первого потомка (т. е. первого внука исходного объекта) и т. д. до нахождения последнего потомка.

На языке InterBase SUSPEND означает, что возвращаемая по RETURNS информация должна заноситься в результирующий набор в виде очередной записи. Первый оператор SUSPEND (строка 11) возвращает значения из первой записи запроса, определяющего непосредственных потомков STARTING_ITEM_ID (строки 5_8). Следующий SUSPEND (строка 17) возвращает результат рекурсив ного вызова процедуры выбора GETCHILDREN. До тех пор пока этот второй вызов находит записи (то есть до тех пор, пока у объекта находятся потомки), второй SUSPEND возвращает их исходной вызывающей процедуре. Когда объекты кончаются, вызывающий код продолжает свою работу и с помощью первого SUSPEND возвращает вторую запись исходного запроса. Если не сбросить переменную ITEMLEVEL во внешнем цикле (строка 10), в ней будет храниться значение из последней итерации внутреннего цикла (строка 15).

Для вызова процедур выборки InterBase следует пользоваться компонентом TQuery, а не TStoredProc. Синтаксис выглядит просто:

with Query1 do begin SQL.Clear; SQL.Add('SELECT * FROM GetChildren(' + IntToStr(CurrentItemID) + ',0)'); Open; end;

Полученный набор будет содержать всех потомков текущего объекта с указанием их уровня.



Содержание раздела