308 lines
7.9 KiB
SQL
Executable File
308 lines
7.9 KiB
SQL
Executable File
set serveroutput on size 32000
|
|
-- show errors;
|
|
|
|
-- Question 1: Retailer detail
|
|
create or replace procedure RetailerDetail (id IN Retailers.RetailerId%TYPE) as
|
|
retailer_id Retailers.RetailerId%TYPE;
|
|
retailer_name Retailers.RetailerName%TYPE;
|
|
retailer_address Retailers.Address%TYPE;
|
|
retailer_orders Orders.Count%TYPE;
|
|
retailer_bestseller_id Products.ProductId%TYPE;
|
|
retailer_bestseller Products.ProductName%TYPE;
|
|
retailer_bestseller_count Orders.Count%TYPE;
|
|
-- CURSOR retailer_cursor IS SELECT RetailerId FROM Retailers WHERE RetailerId=id;
|
|
-- retailer_entry retailer_cursor%ROWTYPE;
|
|
CURSOR order_cursor IS SELECT Count, OrderId FROM Orders WHERE RetailerId=id;
|
|
order_entry order_cursor%ROWTYPE;
|
|
BEGIN
|
|
SELECT RetailerName
|
|
INTO retailer_name
|
|
FROM Retailer
|
|
WHERE RetailerId=id;
|
|
|
|
SELECT Address
|
|
INTO retailer_address
|
|
FROM Retailer
|
|
WHERE RetailerId=id;
|
|
|
|
SELECT COUNT(OrderId)
|
|
INTO retailer_orders
|
|
FROM Orders
|
|
WHERE RetailerId=id;
|
|
|
|
SELECT ProductId
|
|
INTO retailer_bestseller_id
|
|
FROM (
|
|
SELECT ProductId, RANK()
|
|
OVER (ORDER BY Total DESC) AS Score
|
|
FROM (
|
|
SELECT ProductId, SUM(Count) AS Total
|
|
FROM Orders O
|
|
WHERE RetailerId=id
|
|
GROUP BY ProductId
|
|
)
|
|
)
|
|
WHERE Score = 1
|
|
GROUP BY ProductId;
|
|
|
|
SELECT ProductName
|
|
INTO retailer_bestseller
|
|
FROM Products
|
|
WHERE ProductId=retailer_bestseller_id;
|
|
|
|
SELECT SUM(Count)
|
|
INTO retailer_bestseller_count
|
|
FROM Orders
|
|
WHERE ProductId=retailer_bestseller_id AND RetailerId=id;
|
|
|
|
dbms_output.put_line('Retailer Name: ' || retailer_name);
|
|
dbms_output.put_line('Retailer Address: ' || retailer_address);
|
|
dbms_output.put_line('Retailer Total Orders: ' || retailer_orders);
|
|
dbms_output.put_line('Most Popular Product: ' || retailer_bestseller);
|
|
dbms_output.put_line('Total Sold: ' || retailer_bestseller_count);
|
|
END RetailerDetail;
|
|
/
|
|
|
|
-- show error procedure RetailerDetail;
|
|
|
|
-- make test cases yourselves
|
|
BEGIN
|
|
RetailerDetail(1); -- Inferno, 115
|
|
RetailerDetail(2); -- Macbook, 12
|
|
RetailerDetail(3); -- Nike sports jacket, 3
|
|
RetailerDetail(4); -- OnePlus 5t, 1
|
|
RetailerDetail(5); -- Pixel Book, 1
|
|
end;
|
|
/
|
|
|
|
-- Queation 2: Monthly delay report
|
|
create or replace procedure MonthlyDelayReport as
|
|
order_date VARCHAR(32);
|
|
order_count Orders.Count%TYPE;
|
|
order_year VARCHAR(32);
|
|
order_month VARCHAR(32);
|
|
retailer_name Retailers.RetailerName%TYPE;
|
|
CURSOR c_month IS
|
|
SELECT Year, Month, Total
|
|
FROM (
|
|
SELECT Year, Month, COUNT(OrderId) AS Total
|
|
FROM (
|
|
-- EXTRACT
|
|
SELECT EXTRACT(YEAR FROM OrderDate) AS Year, EXTRACT(MONTH FROM OrderDate) AS Month, OrderId, Status
|
|
FROM Orders
|
|
)
|
|
WHERE Status = 'DELAYED'
|
|
GROUP BY Year, Month
|
|
ORDER BY Year ASC, Month ASC
|
|
)
|
|
WHERE Total > 0;
|
|
CURSOR c_retailer IS
|
|
SELECT DISTINCT R.RetailerName
|
|
INTO retailer_name
|
|
FROM (
|
|
SELECT RetailerId
|
|
FROM Orders
|
|
WHERE EXTRACT(YEAR FROM OrderDate) = order_year AND EXTRACT(MONTH FROM OrderDate) = order_month AND Status = 'DELAYED'
|
|
) K, Retailers R
|
|
WHERE R.RetailerId = K.RetailerId
|
|
ORDER BY R.RetailerName ASC;
|
|
BEGIN
|
|
OPEN c_month;
|
|
|
|
LOOP
|
|
FETCH c_month INTO order_year, order_month, order_count;
|
|
EXIT WHEN c_month%NOTFOUND;
|
|
dbms_output.put_line('Delayed orders in ' || order_year || '-' || order_month || ': ' || order_count);
|
|
|
|
dbms_output.put_line('Retailers with delayed orders:');
|
|
OPEN c_retailer;
|
|
|
|
LOOP
|
|
FETCH c_retailer INTO retailer_name;
|
|
EXIT WHEN c_retailer%NOTFOUND;
|
|
dbms_output.put_line('- ' || retailer_name);
|
|
END LOOP;
|
|
|
|
CLOSE c_retailer;
|
|
END LOOP;
|
|
|
|
CLOSE c_month;
|
|
END MonthlyDelayReport;
|
|
/
|
|
|
|
-- show error procedure MonthlyDelayReport;
|
|
|
|
BEGIN
|
|
MonthlyDelayReport;
|
|
End;
|
|
/
|
|
|
|
-- Question 3: Find the product with least profit in each category
|
|
create or replace procedure LeastProfitProduct as
|
|
product_category Products.Category%TYPE;
|
|
product_name Products.ProductName%TYPE;
|
|
product_profit Products.ExfactoryPrice%TYPE;
|
|
CURSOR c_profit IS
|
|
SELECT ProductName, AverageProfit
|
|
FROM (
|
|
SELECT P.ProductName, AverageProfit, RANK()
|
|
OVER (ORDER BY AverageProfit ASC) AS Score
|
|
FROM (
|
|
SELECT ProductId, AVG(ProfitMargin) AS AverageProfit
|
|
FROM (
|
|
SELECT O.OrderId, O.ProductId, O.UnitPrice - P.ExFactoryPrice AS ProfitMargin
|
|
FROM Orders O, Products P
|
|
WHERE O.ProductId = P.ProductId AND P.Category = product_category
|
|
)
|
|
GROUP BY ProductId
|
|
) K, Products P
|
|
WHERE K.ProductId = P.ProductId
|
|
ORDER BY AverageProfit DESC, P.ProductName ASC
|
|
)
|
|
WHERE Score = 1;
|
|
CURSOR c_category IS
|
|
SELECT DISTINCT Category
|
|
FROM Products;
|
|
BEGIN
|
|
OPEN c_category;
|
|
|
|
LOOP
|
|
FETCH c_category INTO product_category;
|
|
EXIT WHEN c_category%NOTFOUND;
|
|
dbms_output.put_line('Least Profit in ' || product_category);
|
|
|
|
OPEN c_profit;
|
|
|
|
LOOP
|
|
FETCH c_profit INTO product_name, product_profit;
|
|
EXIT WHEN c_profit%NOTFOUND;
|
|
dbms_output.put_line('- ' || product_name || ': ' || product_profit);
|
|
END LOOP;
|
|
|
|
CLOSE c_profit;
|
|
END LOOP;
|
|
|
|
CLOSE c_category;
|
|
END LeastProfitProduct;
|
|
/
|
|
|
|
BEGIN
|
|
LeastProfitProduct;
|
|
END;
|
|
/
|
|
|
|
-- Queation 4: New table for retailer product category distribution
|
|
create table RetailerCatergoryTable(RetailerId integer, Electronic integer, Apparel integer, Books integer, primary key(RetailerId));
|
|
create or replace procedure RetailerProductCatergory as
|
|
product_category Products.Category%TYPE;
|
|
retailer_id Retailers.RetailerId%TYPE;
|
|
total_electronic integer;
|
|
total_apparel integer;
|
|
total_books integer;
|
|
CURSOR c_retailer IS
|
|
SELECT RetailerId
|
|
FROM Retailers;
|
|
CURSOR c_category IS
|
|
SELECT COUNT(OrderId) AS Total
|
|
FROM Orders O, Products P
|
|
WHERE O.ProductId = P.ProductId AND P.Category = product_category AND O.RetailerId = retailer_id;
|
|
BEGIN
|
|
OPEN c_retailer;
|
|
|
|
LOOP
|
|
FETCH c_retailer INTO retailer_id;
|
|
EXIT WHEN c_retailer%NOTFOUND;
|
|
|
|
product_category := 'electronics';
|
|
SELECT COUNT(OrderId)
|
|
INTO total_electronic
|
|
FROM Orders O, Products P
|
|
WHERE O.ProductId = P.ProductId AND P.Category = product_category AND O.RetailerId = retailer_id;
|
|
|
|
product_category := 'apparel';
|
|
SELECT COUNT(OrderId)
|
|
INTO total_apparel
|
|
FROM Orders O, Products P
|
|
WHERE O.ProductId = P.ProductId AND P.Category = product_category AND O.RetailerId = retailer_id;
|
|
|
|
product_category := 'books';
|
|
SELECT COUNT(OrderId)
|
|
INTO total_books
|
|
FROM Orders O, Products P
|
|
WHERE O.ProductId = P.ProductId AND P.Category = product_category AND O.RetailerId = retailer_id;
|
|
|
|
INSERT INTO RetailerCatergoryTable (RetailerId, Electronic, Apparel, Books) VALUES (retailer_id, total_electronic, total_apparel, total_books);
|
|
END LOOP;
|
|
|
|
CLOSE c_retailer;
|
|
END RetailerProductCatergory;
|
|
/
|
|
|
|
-- show error procedure RetailerProductCatergory;
|
|
|
|
BEGIN
|
|
RetailerProductCatergory;
|
|
END;
|
|
/
|
|
select * from RetailerCatergoryTable;
|
|
|
|
drop table RetailerCatergoryTable;
|
|
|
|
|
|
-- Question 5: Exception Handle
|
|
create or replace procedure CustomerProductInfo(cid IN Customers.CustomerId%TYPE, pid IN Products.ProductId%TYPE) as
|
|
invalid_input EXCEPTION;
|
|
order_date Orders.OrderDate%TYPE;
|
|
check_cid Customers.CustomerId%TYPE;
|
|
check_pid Products.ProductId%TYPE;
|
|
CURSOR c_customer_product IS
|
|
SELECT DISTINCT O.OrderDate
|
|
FROM Orders O, Products P
|
|
WHERE O.ProductId = pid AND O.CustomerId = cid;
|
|
BEGIN
|
|
OPEN c_customer_product;
|
|
|
|
dbms_output.put_line('Records of customer id ' || cid || ' with product id ' || pid || ':');
|
|
|
|
SELECT CustomerId
|
|
INTO check_cid
|
|
FROM Customers
|
|
WHERE CustomerId = cid;
|
|
|
|
SELECT ProductId
|
|
INTO check_pid
|
|
FROM Products
|
|
WHERE ProductId = pid;
|
|
|
|
LOOP
|
|
FETCH c_customer_product INTO order_date;
|
|
EXIT WHEN c_customer_product%NOTFOUND;
|
|
|
|
dbms_output.put_line('OrderDate: ' || order_date);
|
|
END LOOP;
|
|
|
|
CLOSE c_customer_product;
|
|
EXCEPTION
|
|
WHEN no_data_found THEN
|
|
dbms_output.put_line('Invalid customer id or product id!');
|
|
WHEN others THEN
|
|
dbms_output.put_line('Invalid customer id or product id!');
|
|
END CustomerProductInfo;
|
|
/
|
|
|
|
-- show error procedure CustomerProductInfo;
|
|
|
|
BEGIN
|
|
CustomerProductInfo(1,1);
|
|
CustomerProductInfo(-1,1);
|
|
CustomerProductInfo(1,-1);
|
|
CustomerProductInfo(-1,-1);
|
|
CustomerProductInfo(100,100);
|
|
CustomerProductInfo(4,3);
|
|
CustomerProductInfo(2,5);
|
|
CustomerProductInfo(7,11);
|
|
CustomerProductInfo(8,9);
|
|
CustomerProductInfo(9,5);
|
|
END;
|
|
/
|