SQLServerCentral is supported by Red Gate Software Ltd.
 
Log in  ::  Register  ::  Not logged in
Search:  
 
 
        
Home       Members    Calendar    Who's On



Membership constraint Expand / Collapse
Author
Message
Posted Thursday, November 05, 2009 10:19 PM
SSC-Enthusiastic

SSC-EnthusiasticSSC-EnthusiasticSSC-EnthusiasticSSC-EnthusiasticSSC-EnthusiasticSSC-EnthusiasticSSC-EnthusiasticSSC-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



Post #814699
Posted Friday, November 06, 2009 6:12 AM


SSCrazy

SSCrazySSCrazySSCrazySSCrazySSCrazySSCrazySSCrazySSCrazy

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.
Post #814881
Posted Friday, November 06, 2009 6:26 AM


Hall of Fame

Hall of FameHall of FameHall of FameHall of FameHall of FameHall of FameHall of FameHall of FameHall 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.
Post #814886
Posted Friday, November 06, 2009 7:52 AM
SSC-Enthusiastic

SSC-EnthusiasticSSC-EnthusiasticSSC-EnthusiasticSSC-EnthusiasticSSC-EnthusiasticSSC-EnthusiasticSSC-EnthusiasticSSC-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



Post #814934
Posted Friday, November 06, 2009 4:41 PM


SSChasing Mays

SSChasing MaysSSChasing MaysSSChasing MaysSSChasing MaysSSChasing MaysSSChasing MaysSSChasing MaysSSChasing 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
Post #815256
« Prev Topic | Next Topic »


Permissions Expand / Collapse