Advanced SQL Programming				Fall 2002

		In-class/take-home exercises for Nov. 11th

1.  Trigger to allow adding new customers but not existing customers -
somewhat artificial, since index on custnum prevents this error before
the trigger can work; using name for demonstration purposes.

sp_helptext custcheck_trig

create trigger custcheck_trig
on customer
for insert
as
if (select count(*)
     from customer c, inserted i
     where c.lname = i.lname) > 1 
begin
    rollback
    print "Customer already in database."
end
else
    print "New customer added."

Tests (existing customer, new customer):

1> insert into customer
2> values ('111111111', 'Piper', 'Peter', '987 Pepper Lane', 'Pecksville',
3>   'OH', '12345', '555', '555-5555', '2')
4> insert into customer
5> values ('222222222', 'Peters', 'John', '123 Pumpkin Patch', 'Pumpkin
Hollow',
6>   'PA', '13579', '777', '777-7777', '1')
7> go
New customer added.
(1 row affected)
Customer already in database.
(0 rows affected)
1> select * from customer
2> where lname in ('Peters', 'Piper')
3> go
 custnum   lname                fname               
         street                                   city
state
         zip        areacode phone   status 
 --------- -------------------- -------------------- 
        ---------------------------------------- --------------------
----- 
        ---------- -------- ------- ------ 
 776667778 Peters               Pete                
         45 N. Maine                              Macedon              NY   
         14502      800      5557777 2      
 111111111 Piper                Peter               
         987 Pepper Lane                          Pecksville           OH   
         12345      555      555-555 2      

(2 rows affected)
1> 


2.  Create a trigger that deletes an order once all items shipped.
(Note:  Using simpler tables for illustration:  tblBudget and tblSpending.
Will delete appropriate row in tblSpending if budget amount changes, but
not if any remaining budget amount for same region is zero.)

Starting tables:

1> select * from tblBudget
2> go
 regionID budgetAmt                
 -------- ------------------------ 
        7                 1,000.00 
        2                   500.00 
        3                 3,000.00 
        1                 5,000.00 
        4                   500.00 
        1                     0.00 

(6 rows affected)

1> select * from tblSpending
2> go
 regionID spendingAmt              
 -------- ------------------------ 
        1                   100.00 
        1                   100.00 
        2                    50.00 
        4                   300.00 

(4 rows affected)
1> 
 
create trigger dropSpend_trig
on tblBudget
for update
as
if update(budgetAmt)
begin
/* check for null (actually, zero) budgetAmt first  - do not delete */
  if exists (select * 
	     from tblBudget, inserted
	     where tblBudget.regionID = inserted.regionID
	     and tblBudget.budgetAmt = 0)
  begin
	rollback transaction
  	print "Some budget line not specified - no deletion"
  end
  else
/* Not necessary to check @@rowcount if deleting based on primary key */
	begin
         delete tblSpending
         from tblSpending, tblBudget, inserted
         where tblBudget.regionID = inserted.regionID
         and tblSpending.regionID = tblBudget.regionID
	 print "Changed row(s) in tblSpending deleted."
	end
end
else
/* For any update on a different column */
  print "Updated something other than budgetAmt - no change"

/*  Test with update on different col.:  No change message	*/
/*  Test with update on budgetAmt and no zero value:  		*/
/*  corresponding ID row deleted from tblSpending.		*/
/*  Test with update on budgetAmt with zero value in some row:	*/
/*  update OK on other row, but no deletion.			*/

Tests:

1> -- Update a region ID in tblBudget
2> update tblBudget
3> set regionID = 6 where regionID = 7
4> go
Updated something other than budgetAmt - no change
(1 row affected)
1> -- Update budget amount for region 4
2> update tblBudget
3> set budgetAmt = 750
4> where regionID = 4
5> go
Changed row(s) in tblSpending deleted.
(1 row affected)
1> -- Check what happened in tblSpending
2> select * from tblSpending
3> go
 regionID spendingAmt              
 -------- ------------------------ 
        1                   100.00 
        1                   100.00 
        2                    50.00 

(3 rows affected)
1> 
1> -- Update budget amount for one of the region 1 rows
2> update tblBudget
3> set budgetAmt = 2000
4> where regionID = 1
5> and budgetAmt > 0  -- could have specified actual amount instead
6> go
Some budget line not specified - no deletion
1> -- Check what happened in tblSpending
2> select * from tblSpending
3> go
 regionID spendingAmt              
 -------- ------------------------ 
        1                   100.00 
        1                   100.00 
        2                    50.00 

(3 rows affected)
1> -- Check final state of tblBudget
2> select * from tblBudget
3> go
 regionID budgetAmt                
 -------- ------------------------ 
        6                 1,000.00 
        2                   500.00 
        3                 3,000.00 
        1                 5,000.00 
        4                   750.00 
        1                     0.00 

(6 rows affected)
-- Note:  Update was rolled back in addition to no deletion.  Could have
-- written the trigger without "rollback transaction" and just printed
-- the "no deletion" message.

3.  Statement to create an invoice for new or changed order
(Used select all - the select statement should be pared down to what is
needed, and formatted appropriately.)
1> create trigger order_trig
2> on orderdetail
3> for insert, update
4> as
5> select custnum, 
6>         convert(char(4), o.ordnum) Ord#, 
7>         convert(char(12), orderdate, 101) OrderDate, 
8>         convert(char(18), prodname) Product, 
-- Note d.qty, not plain qty, to distinguish between d.qty and i.qty
9>         convert(char(4), d.qty) Qty, 
10>         convert(char(8), price) Price,
11>         convert(char(10), d.qty*price) Total
12>  from ordermaster o, orderdetail d, product p, inserted i
13>  where o.ordnum = d.ordnum
14>  and d.prodnum = p.prodnum
15>  and i.ordnum = d.ordnum
16> go
1>
Tests:  Add an item to an existing order; change qty for an existing item.

1> -- Insert a product for order # 99
2> insert into orderdetail    
3> values (99, 2049, 10, null)
4> -- Change the quantity for product #2050
5> update orderdetail
6> set qty = 1000
7> where ordnum = 99
8> and prodnum = 2050
9> go
 custnum   Ord# OrderDate    Product            Qty  Price    Total      
 --------- ---- ------------ ------------------ ---- -------- ---------- 
 776677778 99   01/02/1999   paper dolls        6       19.99     119.94 
 776677778 99   01/02/1999   tax time           2222    49.99  111077.78 
 776677778 99   01/02/1999   more paper dolls   10      19.99     199.90 

(3 rows affected)
(1 row affected)
 custnum   Ord# OrderDate    Product            Qty  Price    Total      
 --------- ---- ------------ ------------------ ---- -------- ---------- 
 776677778 99   01/02/1999   paper dolls        6       19.99     119.94 
 776677778 99   01/02/1999   tax time           1000    49.99   49990.00 
 776677778 99   01/02/1999   more paper dolls   10      19.99     199.90 

(3 rows affected)
(1 row affected)

4.  Total amount paid per order, including shipping and gift charges.

1> select convert(char(4), o.ordnum) Ord#,
2>   convert(char(12), sum(qty*price)) Subtotal, 
3>   convert(char(12), convert(money, sum(qty*weight*5))) Shipping,
4>   convert(char(12), sum(qty*giftadd)) GiftWrap,
5>   convert(char(12),
6>      convert(money, 
7>      sum(qty*price)+sum(qty*weight*5)+sum(qty*giftadd))) Total
8> from product p, orderdetail od, ordermaster o
9> where o.ordnum = od.ordnum
10> and p.prodnum = od.prodnum
11> group by o.ordnum
12> go
 Ord# Subtotal     Shipping     GiftWrap     Total        
 ---- ------------ ------------ ------------ ------------ 
 81         567.95        99.50        28.50       695.95 
 85        1649.75       307.50        72.50      2029.75 
 86         642.78       478.00        32.50      1153.28 
 87        1426.60       540.00        61.00      2027.60 
 89          99.98        25.00         5.00       129.98 
 90          89.99        12.50         4.00       106.49 
 91         879.88        27.50        44.00       951.38 
 92      166616.67     41662.50      8332.50    216611.67 
 93         269.94        75.00        13.50       358.44 
 94         174.99       157.50         9.00       341.49 
 95         127.98        98.00         6.50       232.48 
 99       50309.84     12700.00      2516.00     65525.84 

(12 rows affected)