solution

advertisement
11.1
Create a view that defines a view named open_items that shows the invoices that haven’t
been paid. This view should return four columns from the Vendors and Invoices tables:
vendor_name, invoice_number, invoice_total, and balance_due (invoice_total –
payment_total – credit_total). However, a row should only be returned when the balance
due is greater than zero, and the rows should be in sequence by vendor_name. Then, run
the script to create the view, and use SQL Developer to review the data that it returns. (You
may have to click on the Refresh button in the Connections window after you click on the
Views node to show the view you just created.)
CREATE OR REPLACE VIEW open_items
AS
SELECT vendor_name, invoice_number, invoice_total,
invoice_total - payment_total - credit_total AS balance_due
FROM vendors JOIN invoices
ON vendors.vendor_id = invoices.vendor_id
WHERE invoice_total - payment_total - credit_total > 0
ORDER BY vendor_name
13.3
Write a script that creates a cursor consisting of vendor_name, invoice_number, and
balance_due for each invoice with a balance due that’s greater than or equal to $5,000. The
rows in this cursor should be sorted in descending sequence by balance due. Then, for each
invoice, display the balance due, invoice number, and vendor name so it looks something
like this:
$19,351.18
P-0608
Malloy Lithographing Inc
CONNECT ap/ap;
SET SERVEROUTPUT ON;
DECLARE
CURSOR invoices_cursor IS
SELECT vendor_name, invoice_number,
invoice_total - payment_total - credit_total AS balance_due
FROM vendors v JOIN invoices i
ON v.vendor_id = i.vendor_id
WHERE invoice_total - payment_total - credit_total >= 5000
ORDER BY balance_due DESC;
invoice_row invoices%ROWTYPE;
BEGIN
FOR invoice_row IN invoices_cursor LOOP
DBMS_OUTPUT.PUT_LINE(
TO_CHAR(invoice_row.balance_due, '$99,999.99') || '
invoice_row.invoice_number || '
' ||
invoice_row.vendor_name);
END LOOP;
END;
/
' ||
15.1
Create a stored procedure named insert_glaccount that lets a user add a new row to the
General_Ledger_Accounts table in the AP schema. This procedure should have two
parameters, one for each of the two columns in this table. Then, code a CALL statement
that tests the procedure. (Note that this table doesn’t allow duplicate account descriptions.)
CREATE OR REPLACE PROCEDURE insert_glaccount
(
account_number_param
NUMBER,
account_description_param
VARCHAR2
)
AS
BEGIN
INSERT INTO general_ledger_accounts
VALUES (account_number_param, account_description_param);
COMMIT;
END;
/
CALL insert_glaccount(700, 'Internet Services');
15.5
Modify the stored procedure that you created in exercise 1 and save it as
insert_glaccount_with_test. This procedure should use the function that you created in step
3 to test whether the account description is going to be okay before it issues the INSERT
statement. If the account description is a duplicate, this procedure should raise an
application error with -20002 as the error number and an error message of
Duplicate account description
CREATE OR REPLACE PROCEDURE insert_glaccount_with_test
(
account_number_param
account_description_param
NUMBER,
VARCHAR2
)
AS
BEGIN
IF test_glaccounts_description(account_description_param) = 1 THEN
RAISE_APPLICATION_ERROR(-20002, 'Duplicate account description.');
ELSE
INSERT INTO general_ledger_accounts
VALUES (account_number_param, account_description_param);
COMMIT;
END IF;
END;
/
16.2
Create a trigger named invoices_after_update_payment for the Invoices table that displays
the vendor name, invoice number, and payment total in the output window whenever the
payment total is increased. Then, test this trigger with an appropriate UPDATE statement.
(A trigger like this could be modified so it stores the data in an audit table.)
CREATE OR REPLACE TRIGGER invoices_after_update_payment
AFTER UPDATE OF payment_total
ON invoices
FOR EACH ROW
WHEN (new.payment_total > old.payment_total)
DECLARE
vendor_name_var VARCHAR2(50);
BEGIN
SELECT vendor_name
INTO vendor_name_var
FROM vendors
WHERE vendor_id = :old.vendor_id;
DBMS_OUTPUT.PUT_LINE('vendor_name:
' || vendor_name_var);
DBMS_OUTPUT.PUT_LINE('invoice_number: ' || :new.invoice_number);
DBMS_OUTPUT.PUT_LINE('payment_total: ' || :new.payment_total);
END;
/
SET SERVEROUTPUT ON;
UPDATE invoices
SET payment_total = 100
WHERE invoice_id = 112;
-- clean up
UPDATE invoices
SET payment_total = 0
WHERE invoice_id = 112;
Download