(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Использование CAST и табличных функций в PL/SQL (Листинги)

Источник: CITFORUM
Джим Козупрински, PC Week/RE

/*
 
// Листинг 1. Функция CAST и табличные функции 
//Содержит практические примеры применения 
// CAST и табличных функций
// 
//автор: Jim Czuprynski
//
// Предупреждение:
// Этот скрипт предназначен только для демонстрации различных
// возможности Oracle и должен быть тщательнопроверен перед выполнением 
// на любой работающей базе данных Oracle, чтобы исключить какую-либо 
// потенциальную опасность.
//
*/
-----
-- Листинг1.1: Сортировка PL/SQL, включаемая по CAST
-----

DROP TYPE person_names_t;
CREATE OR REPLACE TYPE person_names_t AS TABLE OF VARCHAR2(100);

SET SERVEROUTPUT ON 
DECLARE
 -- List of presidents since 1932, in no particular order
 presidents_t person_names_t := person_names_t(
 'Bush, George W. - 2000', 
 'Bush, George H. W. - 1988', 
 'Johnson, Lyndon B. - 1963',
 'Reagan, Ronald W. - 1980', 
 'Clinton, William J. -1992',
 'Truman, Harry S. - 1945',
 'Roosevelt, Franklin D. - 1932',
 'Eisenhower, Dwight D. - 1952',
 'Kennedy, John F. - 1960',
 'Nixon, Richard M. - 1968',
 'Ford, Gerald R. - 1976',
 'Carter, Jimmy - 1980'
 );
BEGIN
 -- Display all table entries in descending sequence
 DBMS_OUTPUT.PUT_LINE('Presidents after 1932, 
		 in reverse alphabetical order:');
 FOR rec IN (SELECT column_value favs
 FROM TABLE (CAST (presidents_t AS person_names_t))
 ORDER BY column_value DESC)
 LOOP
 DBMS_OUTPUT.PUT_LINE(rec.favs);
 END LOOP;

EXCEPTION
 WHEN OTHERS THEN 
 NULL;
END;
/

статья

-----
-- Листинг 1.2: Использование CAST с групповыми функциями
-----
DROP TYPE numbers_t;
CREATE OR REPLACE TYPE numbers_t AS TABLE OF NUMBER(10);

DECLARE 
 random_numbers numbers_t := numbers_t(
 1000, 
 100, 
 500, 
 3000,
 4000, 
 2000, 
 300, 
 400, 
 200
 );
 tot_entries NUMBER(10) := 0;
 sum_number NUMBER(10) := 0;
 min_number NUMBER(10) := 0;
 max_number NUMBER(10) := 0;
BEGIN

 SELECT 
 SUM(Column_value) total,
 COUNT(Column_value) tally,
 MIN(Column_value) bottom,
 MAX(Column_value) top
 INTO 
 sum_number,
 tot_entries,
 min_number,
 max_number
 FROM TABLE(CAST(random_numbers AS numbers_t));

 DBMS_OUTPUT.PUT_LINE('Results from Random Number Survey');
 DBMS_OUTPUT.PUT_LINE('Count: ' // tot_entries );
 DBMS_OUTPUT.PUT_LINE('Total: ' // sum_number );
 DBMS_OUTPUT.PUT_LINE('Minimum: ' // min_number );
 DBMS_OUTPUT.PUT_LINE('Maximum: ' // max_number );

EXCEPTION
 WHEN OTHERS THEN 
 NULL;
END;
/

статья

 
-----
-- Листинг 1.3: Создание объектных TYPE и табличная функция
-----
DROP TYPE wgt_cost_ctr;
DROP TYPE wgt_cost_ctr_t;

CREATE OR REPLACE TYPE wgt_cost_ctr IS OBJECT (
 cc_lvl NUMBER(3),
 cc_nbr NUMBER(5),
 cc_value VARCHAR2(32)
);

CREATE OR REPLACE TYPE wgt_cost_ctr_t AS TABLE OF wgt_cost_ctr;

CREATE OR REPLACE FUNCTION hr.sf_gather_cost_centers (
 a_employee_id IN hr.employees.employee_id%TYPE
) RETURN hr.wgt_cost_ctr_t
IS
/*
// Функция: sf_gather_cost_centers
//
// Описание: Использование типа Cost Center, ассоциированного с имеющимся
// списком служащих для выбора кредитных организаций, подходящих к иерархии
// Отделение/Отдел/Служащий
*/
 l_department_id NUMBER(5) := 0;
 l_division_id NUMBER(5) := 0;
 retval wgt_cost_ctr_t := wgt_cost_ctr_t();

 CURSOR cur_cost_ctr_asgn (
 a_entity_id IN hr.cost_center_assignments.entity_id%TYPE,
 a_entity_type IN hr.cost_center_assignments.entity_type%TYPE
 ) IS 
 SELECT 
 DECODE(a_entity_type,'V', 1, 'D', 2, 'E', 3, NULL) cc_lvl,
 CCA.cost_ctr_id cc_nbr,
 CC.description cc_value
 FROM 
 hr.cost_center_assignments CCA,
 hr.cost_centers CC
 WHERE CCA.COST_CTR_ID = CC.COST_CTR_ID 
 AND CCA.entity_id = a_entity_id
 AND CCA.entity_type = a_entity_type;

 PROCEDURE expand_collection (cc_in IN wgt_cost_ctr)
 IS
 /*
 // Procedure: expand_collection
 // Adds the specified entry to the collection
 */
 BEGIN
 retval.EXTEND;
 retval(retval.LAST) := cc_in;
 END;
 
BEGIN

 -- Get the Department ID and Division ID for the specified Employee
 SELECT 
 E.department_id,
 D.division_id
 INTO
 l_department_id,
 l_division_id
 FROM 
 hr.employees E,
 hr.departments D,
 hr.divisions V
 WHERE E.Department_Id = D.Department_Id
 AND D.division_id = V.division_id
 AND E.employee_id = a_employee_id;


 -- Gather eligible Cost Centers for the specified Employee
 FOR rec_cost_ctr_asgn IN cur_cost_ctr_asgn(a_employee_id, 'E')
 LOOP
 expand_collection(wgt_cost_ctr(
 rec_cost_ctr_asgn.cc_lvl,
 rec_cost_ctr_asgn.cc_nbr,
 rec_cost_ctr_asgn.cc_value)
 );
 END LOOP;
 
 -- Gather eligible Cost Centers for the specified Employee's Department
 FOR rec_cost_ctr_asgn IN cur_cost_ctr_asgn(l_department_id, 'D')
 LOOP
 expand_collection(wgt_cost_ctr(
 rec_cost_ctr_asgn.cc_lvl,
 rec_cost_ctr_asgn.cc_nbr,
 rec_cost_ctr_asgn.cc_value)
 );
 END LOOP;

 -- Gather eligible Cost Centers for the specified Employee's Division
 FOR rec_cost_ctr_asgn IN cur_cost_ctr_asgn(l_division_id, 'V')
 LOOP
 expand_collection(wgt_cost_ctr(
 rec_cost_ctr_asgn.cc_lvl,
 rec_cost_ctr_asgn.cc_nbr,
 rec_cost_ctr_asgn.cc_value)
 );
 END LOOP;
 
 RETURN retval;
 
EXCEPTION
 WHEN OTHERS THEN 
 dbms_output.put_line('Fatal error encountered!');
 RETURN retval;
 
END sf_gather_cost_centers;
/

статья

 
-----
-- Листинг 1.4: Использование табличной функции с CAST
-----

SELECT *
 FROM TABLE (CAST (sf_gather_cost_centers (114) 
 AS wgt_cost_ctr_t));

SELECT * 
 FROM TABLE (CAST (sf_gather_cost_centers (120) 
 AS wgt_cost_ctr_t));

SELECT * FROM ( 
 SELECT 
 DISTINCT * 
 FROM TABLE (CAST (sf_gather_cost_centers (120) 
 AS wgt_cost_ctr_t))
 ORDER BY cc_lvl DESC
 )
WHERE rownum <= 5;

статья

 
-----
-- Листинг 1.5: Использование коныейерной (PIPELINED) табличной функции
-----
CREATE OR REPLACE FUNCTION hr.sf_gather_cost_centers (
 a_employee_id IN hr.employees.employee_id%TYPE
) RETURN hr.wgt_cost_ctr_t PIPELINED 
IS
/*
// Функция: sf_gather_cost_centers (конвейерная)
//
//
//
*/
 l_department_id NUMBER(5) := 0;
 l_division_id NUMBER(5) := 0;

 CURSOR cur_cost_ctr_asgn (
 a_entity_id IN hr.cost_center_assignments.entity_id%TYPE,
 a_entity_type IN hr.cost_center_assignments.entity_type%TYPE
 ) IS 
 SELECT 
 DECODE(a_entity_type,'V', 1, 'D', 2, 'E', 3, NULL) cc_lvl,
 CCA.cost_ctr_id cc_nbr,
 CC.description cc_value
 FROM 
 hr.cost_center_assignments CCA,
 hr.cost_centers CC
 WHERE CCA.COST_CTR_ID = CC.COST_CTR_ID 
 AND CCA.entity_id = a_entity_id
 AND CCA.entity_type = a_entity_type;

BEGIN

 -- Get the Department ID and Division ID for the specified Employee
 SELECT 
 E.department_id,
 D.division_id
 INTO
 l_department_id,
 l_division_id
 FROM 
 hr.employees E,
 hr.departments D,
 hr.divisions V
 WHERE E.Department_Id = D.Department_Id
 AND D.division_id = V.division_id
 AND E.employee_id = a_employee_id;


 -- Gather eligible Cost Centers for the specified Employee
 FOR rec_cost_ctr_asgn IN cur_cost_ctr_asgn(a_employee_id, 'E')
 LOOP
 PIPE ROW(wgt_cost_ctr(
 rec_cost_ctr_asgn.cc_lvl,
 rec_cost_ctr_asgn.cc_nbr,
 rec_cost_ctr_asgn.cc_value)
 );
 END LOOP;

 -- Gather eligible Cost Centers for the specified Employee's Department
 FOR rec_cost_ctr_asgn IN cur_cost_ctr_asgn(l_department_id, 'D')
 LOOP
 PIPE ROW(wgt_cost_ctr(
 rec_cost_ctr_asgn.cc_lvl,
 rec_cost_ctr_asgn.cc_nbr,
 rec_cost_ctr_asgn.cc_value)
 );
 END LOOP;

 -- Gather eligible Cost Centers for the specified Employee's Division
 FOR rec_cost_ctr_asgn IN cur_cost_ctr_asgn(l_division_id, 'V')
 LOOP
 PIPE ROW(wgt_cost_ctr(
 rec_cost_ctr_asgn.cc_lvl,
 rec_cost_ctr_asgn.cc_nbr,
 rec_cost_ctr_asgn.cc_value)
 );
 END LOOP;
 
 RETURN;
 
EXCEPTION
 WHEN OTHERS THEN 
 dbms_output.put_line('Fatal error encountered!');
 RETURN;
 
END sf_gather_cost_centers;
/

статья

 
-----
-- Листинг 1.6: Использование конвейерной табличной функции с CAST
-----
SELECT * 
 FROM TABLE (sf_gather_cost_centers (114));

SELECT * 
 FROM TABLE (sf_gather_cost_centers (120));

SELECT * FROM ( 
 SELECT 
 DISTINCT * 
 FROM TABLE (sf_gather_cost_centers (120)) 
 ORDER BY cc_lvl DESC
 )
WHERE rownum <= 5;



статья

-------------------------------------------------------------------------

Листинг 2. 

/* 
// Примеры CAST и табличных функций 
//
// Этот скрипт содержит DDL- и DML- предложения, требуемые для
// создания новых таблиц и модификации существующих в учебной
// схеме HR базы данных Oracle для демонстрации возможностей функции
// CAST и табличных функций
//
// Автор: Jim Czuprynski
//
/ Предупреждение:
// Этот скрипт предназначен только для демонстрации различных
// возможности Oracle и должен быть тщательнопроверен перед выполнением 
// на любой работающей базе данных Oracle, чтобы исключить какую-либо 
// потенциальную опасность.
//
*/

-----
-- Create and load new table in the HR schema to store Divisions
-----
DROP TABLE hr.divisions CASCADE CONSTRAINTS;
CREATE TABLE hr.divisions (
 division_id NUMBER(5) PRIMARY KEY,
 description VARCHAR2(32) NOT NULL
);

INSERT INTO hr.divisions (division_id, description)
VALUES (10000, 'Executive');
INSERT INTO hr.divisions (division_id, description)
VALUES (20000, 'Administrative');
INSERT INTO hr.divisions (division_id, description)
VALUES (30000, 'Construction');

COMMIT;

-----
-- Create and populate new DIVISION_ID column in the DEPARTMENTS table
-----
ALTER TABLE hr.departments ADD division_id NUMBER(5);
ALTER TABLE hr.departments 
 ADD CONSTRAINT department_division_fk
 FOREIGN KEY (division_id)
 REFERENCES hr.divisions(division_id);

-- Assign departments to Executive division
UPDATE hr.departments
 SET division_id = 10000
 WHERE department_id IN (10, 20, 40, 60, 70, 80, 90);

COMMIT;
 
-- Assign departments to Construction division 
UPDATE hr.departments
 SET division_id = 30000
 WHERE department_id IN (30, 50, 170, 180, 190, 200);

COMMIT;
 
-- Assign all other departments to Administrative division
UPDATE hr.departments
 SET division_id = 20000
 WHERE division_id IS NULL;

COMMIT;

-----
-- Create and load a new table in the HR schema to store Cost Centers
-----
DROP TABLE hr.cost_centers CASCADE CONSTRAINTS;
CREATE TABLE hr.cost_centers (
 cost_ctr_id NUMBER(5) PRIMARY KEY,
 description VARCHAR2(32) NOT NULL,
 selectable CHAR(1) NOT NULL
);

ALTER TABLE hr.cost_centers 
 ADD CONSTRAINT cc_selectable_ck 
 CHECK (selectable IN ('Y','N'));

INSERT INTO hr.cost_centers 
(cost_ctr_id, description, selectable)
VALUES (10000, 'Sales and Management', 'N');
INSERT INTO hr.cost_centers 
(cost_ctr_id, description, selectable)
VALUES (20000, 'Administrative', 'Y');
INSERT INTO hr.cost_centers 
(cost_ctr_id, description, selectable)
VALUES (30000, 'Homebuilding', 'Y');

INSERT INTO hr.cost_centers 
(cost_ctr_id, description, selectable)
VALUES (11000, 'Owners', 'N');
INSERT INTO hr.cost_centers 
(cost_ctr_id, description, selectable)
VALUES (12000, 'Sales and Marketing', 'Y');
INSERT INTO hr.cost_centers 
(cost_ctr_id, description, selectable)
VALUES (12100, 'Outside Sales', 'Y');
INSERT INTO hr.cost_centers 
(cost_ctr_id, description, selectable)
VALUES (12200, 'Sales Support', 'Y');

INSERT INTO hr.cost_centers 
(cost_ctr_id, description, selectable)
VALUES (21000, 'Office Supplies', 'Y');
INSERT INTO hr.cost_centers 
(cost_ctr_id, description, selectable)
VALUES (22000, 'Human Resources', 'N');
INSERT INTO hr.cost_centers 
(cost_ctr_id, description, selectable)
VALUES (23000, 'Architectural', 'Y');
INSERT INTO hr.cost_centers 
(cost_ctr_id, description, selectable)
VALUES (23100, 'Blueprinting', 'Y');
INSERT INTO hr.cost_centers 
(cost_ctr_id, description, selectable)
VALUES (23200, 'Planning', 'Y');

INSERT INTO hr.cost_centers 
(cost_ctr_id, description, selectable)
VALUES (31000, 'Exterior Construction', 'Y');
INSERT INTO hr.cost_centers 
(cost_ctr_id, description, selectable)
VALUES (31100, 'Wall and Floor Setting', 'Y');
INSERT INTO hr.cost_centers 
(cost_ctr_id, description, selectable)
VALUES (31200, 'Concrete and Foundation', 'Y');
INSERT INTO hr.cost_centers 
(cost_ctr_id, description, selectable)
VALUES (31300, 'Rough Landscaping', 'Y');
INSERT INTO hr.cost_centers 
(cost_ctr_id, description, selectable)
VALUES (31400, 'Finish Landscaping', 'Y');
INSERT INTO hr.cost_centers 
(cost_ctr_id, description, selectable)
VALUES (32000, 'Carpentry - General', 'Y');
INSERT INTO hr.cost_centers 
(cost_ctr_id, description, selectable)
VALUES (32100, 'Rough Carpentry', 'Y');
INSERT INTO hr.cost_centers 
(cost_ctr_id, description, selectable)
VALUES (32200, 'Finish Carpentry', 'Y');
INSERT INTO hr.cost_centers 
(cost_ctr_id, description, selectable)
VALUES (33000, 'Plumbing - General', 'Y');
INSERT INTO hr.cost_centers 
(cost_ctr_id, description, selectable)
VALUES (33100, 'Rough-In Plumbing', 'Y');
INSERT INTO hr.cost_centers 
(cost_ctr_id, description, selectable)
VALUES (33200, 'Finish Plumbing', 'Y');
INSERT INTO hr.cost_centers 
(cost_ctr_id, description, selectable)
VALUES (34000, 'Physical Plant', 'Y');
INSERT INTO hr.cost_centers 
(cost_ctr_id, description, selectable)
VALUES (34100, 'HVAC', 'Y');
INSERT INTO hr.cost_centers 
(cost_ctr_id, description, selectable)
VALUES (35000, 'Interior Construction', 'Y');
INSERT INTO hr.cost_centers 
(cost_ctr_id, description, selectable)
VALUES (35100, 'Wallboarding and Plastering', 'Y');
INSERT INTO hr.cost_centers 
(cost_ctr_id, description, selectable)
VALUES (35200, 'Painting', 'Y');
INSERT INTO hr.cost_centers 
(cost_ctr_id, description, selectable)
VALUES (35300, 'Flooring', 'Y');

COMMIT;

-----
-- Create table for Cost Center Assignments
-----
DROP TABLE hr.cost_center_assignments CASCADE CONSTRAINTS;
CREATE TABLE hr.cost_center_assignments (
 entity_id NUMBER(5) NOT NULL,
 entity_type CHAR(1) NOT NULL,
 seq_nbr NUMBER(5) NOT NULL,
 cost_ctr_id NUMBER(5) NOT NULL
);

ALTER TABLE hr.cost_center_assignments
 ADD CONSTRAINT cost_center_assignments_pk
 PRIMARY KEY (entity_id, entity_type, seq_nbr);

ALTER TABLE hr.cost_center_assignments
 ADD CONSTRAINT cost_center_assignments_fk
 FOREIGN KEY (cost_ctr_id)
 REFERENCES hr.cost_centers(cost_ctr_id);

-- Load Division-level cost center assignments
INSERT INTO hr.cost_center_assignments 
(entity_id, entity_type, seq_nbr, cost_ctr_id)
VALUES (10000, 'V', 1, 10000);
INSERT INTO hr.cost_center_assignments 
(entity_id, entity_type, seq_nbr, cost_ctr_id)
VALUES (20000, 'V', 1, 20000);
INSERT INTO hr.cost_center_assignments 
(entity_id, entity_type, seq_nbr, cost_ctr_id)
VALUES (30000, 'V', 1, 30000);
COMMIT;

-- Load Department-level cost center assignments
INSERT INTO hr.cost_center_assignments 
(entity_id, entity_type, seq_nbr, cost_ctr_id)
VALUES (30, 'D', 1, 21000);
INSERT INTO hr.cost_center_assignments 
(entity_id, entity_type, seq_nbr, cost_ctr_id)
VALUES (30, 'D', 2, 23100);
INSERT INTO hr.cost_center_assignments 
(entity_id, entity_type, seq_nbr, cost_ctr_id)
VALUES (30, 'D', 3, 23200);

INSERT INTO hr.cost_center_assignments 
(entity_id, entity_type, seq_nbr, cost_ctr_id)
VALUES (50, 'D', 1, 31000);
INSERT INTO hr.cost_center_assignments 
(entity_id, entity_type, seq_nbr, cost_ctr_id)
VALUES (50, 'D', 2, 33000);
INSERT INTO hr.cost_center_assignments 
(entity_id, entity_type, seq_nbr, cost_ctr_id)
VALUES (50, 'D', 3, 33000);
INSERT INTO hr.cost_center_assignments 
(entity_id, entity_type, seq_nbr, cost_ctr_id)
VALUES (50, 'D', 4, 34000);
INSERT INTO hr.cost_center_assignments 
(entity_id, entity_type, seq_nbr, cost_ctr_id)
VALUES (50, 'D', 5, 35000);

INSERT INTO hr.cost_center_assignments 
(entity_id, entity_type, seq_nbr, cost_ctr_id)
VALUES (80, 'D', 1, 12000);
INSERT INTO hr.cost_center_assignments 
(entity_id, entity_type, seq_nbr, cost_ctr_id)
VALUES (80, 'D', 2, 12100);
INSERT INTO hr.cost_center_assignments 
(entity_id, entity_type, seq_nbr, cost_ctr_id)
VALUES (80, 'D', 3, 12200);
INSERT INTO hr.cost_center_assignments 
(entity_id, entity_type, seq_nbr, cost_ctr_id)
VALUES (80, 'D', 4, 21000);

INSERT INTO hr.cost_center_assignments 
(entity_id, entity_type, seq_nbr, cost_ctr_id)
VALUES (110, 'D', 1, 21000);

-- Load Employee-level cost center assignments

INSERT INTO hr.cost_center_assignments 
(entity_id, entity_type, seq_nbr, cost_ctr_id)
VALUES (114, 'E', 1, 35100);

INSERT INTO hr.cost_center_assignments 
(entity_id, entity_type, seq_nbr, cost_ctr_id)
VALUES (120, 'E', 1, 35100);
INSERT INTO hr.cost_center_assignments 
(entity_id, entity_type, seq_nbr, cost_ctr_id)
VALUES (120, 'E', 2, 35200);
INSERT INTO hr.cost_center_assignments 
(entity_id, entity_type, seq_nbr, cost_ctr_id)
VALUES (120, 'E', 3, 35300);

COMMIT;

-----
-- Sample queries
-----
 
-- Show all Cost Center entries
SELECT * 
 FROM HR.cost_centers 
 ORDER BY cost_ctr_id

-- Show all Cost Center Assignment entries
SELECT * 
 FROM HR.cost_center_assignments 

-- Show all Division / Department / Employee hierarchy entries and details
SELECT 
 D.division_id,
 V.description,
 D.department_name,
 E.department_id,
 E.employee_id,
 E.last_name
 FROM 
 divisions V,
 departments D,
 employees E
 WHERE E.department_id = D.department_id
 AND d.division_id = V.division_id
 ORDER BY D.Division_Id, e.department_id, e.employee_id


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 17.05.2006 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Oracle Database Standard Edition 2 Processor License
Oracle Database Personal Edition Named User Plus Software Update License & Support
Oracle Database Standard Edition 2 Named User Plus License
Oracle Database Personal Edition Named User Plus License
Купить Антивирус Dr.Web Server Security Suite для сервера
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
СУБД Oracle "с нуля"
eManual - электронные книги и техническая документация
Компьютерная библиотека: книги, статьи, полезные ссылки
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100