ALTER SESSION SET CONTAINER=SAKILA; BEGIN FOR r IN (SELECT * FROM user_types) LOOP EXECUTE IMMEDIATE 'DROP TYPE ' || r.type_name || ' FORCE'; END LOOP; END; / CREATE TYPE LANGUAGE_T AS OBJECT ( language_id SMALLINT, name CHAR(20), last_update DATE ); / CREATE TYPE LANGUAGES_T AS TABLE OF LANGUAGE_T; / CREATE TYPE FILM_T AS OBJECT ( film_id int, title VARCHAR(255), description CLOB, release_year VARCHAR(4), language LANGUAGE_T, original_language LANGUAGE_T, rental_duration SMALLINT, rental_rate DECIMAL(4,2), length SMALLINT, replacement_cost DECIMAL(5,2), rating VARCHAR(10), special_features VARCHAR(100), last_update DATE ); / CREATE TYPE FILMS_T AS TABLE OF FILM_T; / CREATE TYPE ACTOR_T AS OBJECT ( actor_id numeric, first_name VARCHAR(45), last_name VARCHAR(45), last_update DATE ); / CREATE TYPE ACTORS_T AS TABLE OF ACTOR_T; / CREATE TYPE CATEGORY_T AS OBJECT ( category_id SMALLINT, name VARCHAR(25), last_update DATE ); / CREATE TYPE CATEGORIES_T AS TABLE OF CATEGORY_T; / CREATE TYPE FILM_INFO_T AS OBJECT ( film FILM_T, actors ACTORS_T, categories CATEGORIES_T ); / CREATE TYPE COUNTRY_T AS OBJECT ( country_id SMALLINT, country VARCHAR(50), last_update DATE ); / CREATE TYPE CITY_T AS OBJECT ( city_id int, city VARCHAR(50), country COUNTRY_T, last_update DATE ); / CREATE TYPE ADDRESS_T AS OBJECT ( address_id int, address VARCHAR(50), address2 VARCHAR(50), district VARCHAR(20), city CITY_T, postal_code VARCHAR(10), phone VARCHAR(20), last_update DATE ); / CREATE TYPE CUSTOMER_T AS OBJECT ( customer_id INT, first_name VARCHAR(45), last_name VARCHAR(45), email VARCHAR(50), address ADDRESS_T, active CHAR(1), create_date DATE, last_update DATE ); / CREATE TYPE CUSTOMERS_T AS TABLE OF CUSTOMER_T; / CREATE TYPE CUSTOMER_RENTAL_HISTORY_T AS OBJECT ( customer CUSTOMER_T, films FILMS_T ); / CREATE OR REPLACE PACKAGE RENTALS AS FUNCTION GET_ACTOR(p_actor_id INT) RETURN ACTOR_T; FUNCTION GET_ACTORS RETURN ACTORS_T; FUNCTION GET_CUSTOMER(p_customer_id INT) RETURN CUSTOMER_T; FUNCTION GET_CUSTOMERS RETURN CUSTOMERS_T; FUNCTION GET_FILM(p_film_id INT) RETURN FILM_T; FUNCTION GET_FILMS RETURN FILMS_T; FUNCTION GET_CUSTOMER_RENTAL_HISTORY(p_customer_id INT) RETURN CUSTOMER_RENTAL_HISTORY_T; FUNCTION GET_CUSTOMER_RENTAL_HISTORY(p_customer CUSTOMER_T) RETURN CUSTOMER_RENTAL_HISTORY_T; FUNCTION GET_FILM_INFO(p_film_id INT) RETURN FILM_INFO_T; FUNCTION GET_FILM_INFO(p_film FILM_T) RETURN FILM_INFO_T; END RENTALS; / CREATE OR REPLACE PACKAGE BODY RENTALS AS FUNCTION GET_ACTOR(p_actor_id INT) RETURN ACTOR_T IS v_result ACTOR_T; BEGIN SELECT ACTOR_T( a.actor_id, a.first_name, a.last_name, a.last_update ) INTO v_result FROM actor a WHERE a.actor_id = p_actor_id; RETURN v_result; END GET_ACTOR; FUNCTION GET_ACTORS RETURN ACTORS_T IS v_result ACTORS_T; BEGIN SELECT ACTOR_T( a.actor_id, a.first_name, a.last_name, a.last_update ) BULK COLLECT INTO v_result FROM actor a; RETURN v_result; END GET_ACTORS; FUNCTION GET_CUSTOMER(p_customer_id INT) RETURN CUSTOMER_T IS v_result CUSTOMER_T; BEGIN SELECT CUSTOMER_T( c.customer_id, c.first_name, c.last_name, c.email, ADDRESS_T( a.address_id, a.address, a.address2, a.district, CITY_T( i.city_id, i.city, COUNTRY_T( o.country_id, o.country, o.last_update ), i.last_update ), a.postal_code, a.phone, a.last_update ), c.active, c.create_date, c.last_update ) INTO v_result FROM customer c LEFT JOIN address a ON c.address_id = a.address_id LEFT JOIN city i ON a.city_id = i.city_id LEFT JOIN country o ON i.country_id = o.country_id WHERE c.customer_id = p_customer_id; RETURN v_result; END GET_CUSTOMER; FUNCTION GET_CUSTOMERS RETURN CUSTOMERS_T IS v_result CUSTOMERS_T; BEGIN SELECT CUSTOMER_T( c.customer_id, c.first_name, c.last_name, c.email, ADDRESS_T( a.address_id, a.address, a.address2, a.district, CITY_T( i.city_id, i.city, COUNTRY_T( o.country_id, o.country, o.last_update ), i.last_update ), a.postal_code, a.phone, a.last_update ), c.active, c.create_date, c.last_update ) BULK COLLECT INTO v_result FROM customer c LEFT JOIN address a ON c.address_id = a.address_id LEFT JOIN city i ON a.city_id = i.city_id LEFT JOIN country o ON i.country_id = o.country_id; RETURN v_result; END GET_CUSTOMERS; FUNCTION GET_FILM(p_film_id INT) RETURN FILM_T IS v_result FILM_T; BEGIN SELECT FILM_T( f.film_id, f.title, f.description, f.release_year, NVL2(l1.language_id, LANGUAGE_T( l1.language_id, l1.name, l1.last_update ), NULL ), NVL2(l2.language_id, LANGUAGE_T( l2.language_id, l2.name, l2.last_update ), NULL ), f.rental_duration, f.rental_rate, f.length, f.replacement_cost, f.rating, f.special_features, f.last_update ) INTO v_result FROM film f LEFT JOIN language l1 ON f.language_id = l1.language_id LEFT JOIN language l2 ON f.original_language_id = l2.language_id WHERE f.film_id = p_film_id; RETURN v_result; END GET_FILM; FUNCTION GET_FILMS RETURN FILMS_T IS v_result FILMS_T; BEGIN SELECT FILM_T( f.film_id, f.title, f.description, f.release_year, NVL2(l1.language_id, LANGUAGE_T( l1.language_id, l1.name, l1.last_update ), NULL ), NVL2(l2.language_id, LANGUAGE_T( l2.language_id, l2.name, l2.last_update ), NULL ), f.rental_duration, f.rental_rate, f.length, f.replacement_cost, f.rating, f.special_features, f.last_update ) BULK COLLECT INTO v_result FROM film f LEFT JOIN language l1 ON f.language_id = l1.language_id LEFT JOIN language l2 ON f.original_language_id = l2.language_id; RETURN v_result; END GET_FILMS; FUNCTION GET_CUSTOMER_RENTAL_HISTORY(p_customer_id INT) RETURN CUSTOMER_RENTAL_HISTORY_T IS BEGIN RETURN GET_CUSTOMER_RENTAL_HISTORY(GET_CUSTOMER(p_customer_id)); END GET_CUSTOMER_RENTAL_HISTORY; FUNCTION GET_CUSTOMER_RENTAL_HISTORY(p_customer CUSTOMER_T) RETURN CUSTOMER_RENTAL_HISTORY_T IS v_films FILMS_T; BEGIN SELECT GET_FILM(f.film_id) BULK COLLECT INTO v_films FROM ( SELECT DISTINCT f.film_id FROM film f LEFT JOIN inventory i ON i.film_id = f.film_id LEFT JOIN rental r ON r.inventory_id = i.inventory_id WHERE r.customer_id = p_customer.customer_id ) f ORDER BY f.film_id; RETURN CUSTOMER_RENTAL_HISTORY_T( p_customer, v_films ); END GET_CUSTOMER_RENTAL_HISTORY; FUNCTION GET_FILM_INFO(p_film_id INT) RETURN FILM_INFO_T IS BEGIN RETURN GET_FILM_INFO(GET_FILM(p_film_id)); END GET_FILM_INFO; FUNCTION GET_FILM_INFO(p_film FILM_T) RETURN FILM_INFO_T IS v_actors ACTORS_T; v_categories CATEGORIES_T; BEGIN SELECT ACTOR_T( a.actor_id, a.first_name, a.last_name, a.last_update ) BULK COLLECT INTO v_actors FROM actor a JOIN film_actor fa ON fa.actor_id = a.actor_id WHERE fa.film_id = p_film.film_id ORDER BY a.actor_id; SELECT CATEGORY_T( c.category_id, c.name, c.last_update ) BULK COLLECT INTO v_categories FROM category c JOIN film_category fc ON fc.category_id = c.category_id WHERE fc.film_id = p_film.film_id ORDER BY c.category_id; RETURN FILM_INFO_T( p_film, v_actors, v_categories ); END GET_FILM_INFO; END RENTALS; / CREATE PACKAGE customers AS TYPE person IS RECORD ( first_name VARCHAR2(50), last_name VARCHAR2(50) ); FUNCTION get_customer(p_customer_id NUMBER) RETURN person; END customers; / CREATE PACKAGE BODY customers AS FUNCTION get_customer(p_customer_id NUMBER) RETURN person IS v_person customers.person; BEGIN SELECT c.first_name, c.last_name INTO v_person FROM customer c WHERE c.customer_id = p_customer_id; RETURN v_person; END get_customer; END customers; /