|
|
|
SSC-Enthusiastic
      
Group: General Forum Members
Last Login: Today @ 12:17 AM
Points: 191,
Visits: 405
|
|
Hello all,
I believe this can be done, but wanted to make sure. Ok I have two tables. The Dues table contains the member dues owed by each memeber in a non profit organization (This may difffer between members). The Payment Table contains all the payments the members have paid. There is a relationship between these tables. I wanted to make sure there is a constraint on the Payment table that will not allow the sum of the payments for a member in the payment table to be greater that that member's dues owed in the Dues table.
Is there a way to add a constraint like this? If so, how would I go about doing that?
Thanks,
Strick
|
|
|
|
|
SSCrazy
      
Group: General Forum Members
Last Login: Today @ 4:15 AM
Points: 2,069,
Visits: 2,040
|
|
Generally one would do this with triggers (though you have to be careful to handle UPDATEs and DELETEs on both tables gracefully too), though if you are happy to lose the greater protection afforded by such logic, you could enforce your business rules through the procedures that modify the tables concerned.
The quality of the answers is directly proportional to the quality of the question.
|
|
|
|
|
Hall of Fame
       
Group: General Forum Members
Last Login: Today @ 8:31 PM
Points: 3,439,
Visits: 8,880
|
|
As Paul mentioned, you could add this kind of business logic in a procedure, a trigger or even using udf functions as a constraint...but...
wouldn't that logic prevent any member from paying his dues in advance? i would think that is a very typical scenario, not sure you'd want to institute data restrictions like that without thinking it through.
Lowell help us help you! if your post doesnt have CREATE TABLE YOURTABLENAME and INSERT INTO YOURTABLE SQL statements, chances are you didn't post enough information for us to help you! If you can, avoid pseudocode and show us your actual query...it makes it much better for you to see a good example with your tablenames you'd understand, and be able to copy and paste for immediate testing.
|
|
|
|
|
SSC-Enthusiastic
      
Group: General Forum Members
Last Login: Today @ 12:17 AM
Points: 191,
Visits: 405
|
|
No, a member can pay in advance all the way up to the Dues total for that year. I thought about triggers, but they won't prevent someone from paying too much for a year. I want the dbms to not even allow this to happen. Just like if I try to delete a primary key record that has a foreign key record in another table. The DBMS won't let it happen. I know I can prevent people from paying too much at the front end by making the application check the dues table for that year but I wanted to take the extra step and prevent this from happening at the back end as well.
Thanks,
Strick
|
|
|
|
|
SSChasing Mays
      
Group: General Forum Members
Last Login: Today @ 1:30 AM
Points: 691,
Visits: 1,324
|
|
Maybe you can denormalize the structure a bit, which will make some of the queries simpler as well. You can put sum of payments to the Members table and Update this sum with a trigger on Payments table. Then it is also easy to put a CHECK constraint that will keep the payments below the dues level. I wrote a small testing script, see if this is what you were after:
create table Members ( MemberId int primary key, Dues money, PaymentsSum money, constraint CHK_DuesPayments check(Dues >= PaymentsSum) ) go create table Payments ( MemberId int not null, Payment money, constraint FK_Members foreign key (MemberId) references Members(MemberId) ) go create trigger trg_payment on Payments for insert, update, delete as begin update Members set PaymentsSum = PaymentsSum - b.Payment from Members a inner join (select sum(Payment) Payment, MemberId from deleted d group by MemberId) b on a.MemberId = b.MemberId
update Members set PaymentsSum = PaymentsSum + b.Payment from Members a inner join (select sum(Payment) Payment, MemberId from inserted i group by MemberId) b on a.MemberId = b.MemberId end
go
insert Members(MemberId, Dues, PaymentsSum) values (1, 10, 0) insert Members(MemberId, Dues, PaymentsSum) values (2, 10, 0) insert Members(MemberId, Dues, PaymentsSum) values (3, 10, 0) go --testing inserts-- --these two inserts succeed insert Payments(MemberId, Payment) values (1, 4) select * from Members where MemberId = 1 insert Payments(MemberId, Payment) values (1, 4) select * from Members where MemberId = 1 go --this insert fails because sum of payments is bigger than dues for this member insert Payments(MemberId, Payment) values (1, 4) select * from Members where MemberId = 1 go
--testing updates--
--this will succeed insert Payments(MemberId, Payment) values (2, 10) select * from Members where MemberId = 2 go --this will work as well update Payments set Payment = 5 where MemberId = 2 select * from Members where MemberId = 2 go --this will not work update Payments set Payment = 11 where MemberId = 2 select * from Members where MemberId = 2
go --testing deletes-- --this will succeed insert Payments(MemberId, Payment) values (3, 3) insert Payments(MemberId, Payment) values (3, 3) insert Payments(MemberId, Payment) values (3, 3) select * from Members where MemberId = 3 delete Payments where MemberId = 3 select * from Members where MemberId = 3 select * from Payments go --testing multiple inserts insert Payments(MemberId, Payment) select 3, 3 union all select 3, 3 select * from Members where MemberId = 3 delete Payments where MemberId = 3 select * from Members where MemberId = 3
delete Payments where MemberId = 2
insert Payments(MemberId, Payment) select 3, 3 union all select 3, 3 union all select 2, 3 union all select 2, 1 union all select 3, 3 select * from Members where MemberId in(2, 3) delete Payments where MemberId in (2, 3) select * from Members where MemberId in (2, 3)
go --CLEANUP drop table Payments drop table Members Regards
Piotr
|
|
|
|