Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 SQL Server Development (2000)
 DB Design - Handling payments

Author  Topic 

stephe40
Posting Yak Master

218 Posts

Posted - 2005-07-05 : 14:18:38
So I am working on a reservation management system. I have hit a snag in designing the way it tracks transactions. I want to keep it simple. I don't need any fancy POS style transaction functionality.

How have you guys handled tracking multiple forms of payments and the information that goes along with it?

For example, I have transactions and transaction types tables. When someone pays with a credit card I have two fields in the transaction table, 'ccNum' and 'ccExp' to track that information. But whens someone pays with a check, I need a field to track a check number, so I have a 'checkNum' field. So then I figured, why have the transaction types table? If there is a number in the 'ccNum' field I can tell if it is a credit transaction, and the same for checks, and if both are NULL I can tell if it is a cash transaction.

Any comments would be appreciated.

- Eric

Michael Valentine Jones
Yak DBA Kernel (pronounced Colonel)

7020 Posts

Posted - 2005-07-05 : 15:57:52
I think you should retain the transaction types table, because otherwise you will have to use that logic in each query. Plus later on you may have to handle some other kind of paymnets and the situation will get even more complicated. For example, newspapaer coupons, manufacturers coupons, store credits, wire transfers, etc.

CODO ERGO SUM
Go to Top of Page

stephe40
Posting Yak Master

218 Posts

Posted - 2005-07-05 : 16:17:49
Yeah, we discussed that. After some thought, I am leaning towards keeping the transactions and transaction type tables. And then just having "numbers" and "exp" fields that will store the cc number and experiation date if needed, or just a check number with the exp field null, or both fields would just be blank if its a cash transaction.

- Eric
Go to Top of Page

stephe40
Posting Yak Master

218 Posts

Posted - 2005-07-05 : 16:18:46
I'm just curious what normalization rule is being violated then?

- Eric
Go to Top of Page

Michael Valentine Jones
Yak DBA Kernel (pronounced Colonel)

7020 Posts

Posted - 2005-07-05 : 16:32:29
I would keep the individual columns, because it make it easier to apply rules for allowable data.

You could have tables specific for handeling each type of payment transaction. If the data is different enough for each one. that may be a better option. You might have a payment line item, with generic information, like date and amount, and then tables that are related to it by (0 or 1) to 1 relationships for specific types of transactions.

CODO ERGO SUM
Go to Top of Page

rockmoose
SQL Natt Alfen

3279 Posts

Posted - 2005-07-05 : 18:32:58
quote:
Originally posted by stephe40

I'm just curious what normalization rule is being violated then?

- Eric



The way You have described things, I don't think any normal form is being violated.
All attributes in the transaction table would be dependent on the key or a superkey of the table:
{Key} -> {TransactionType,Date,Amount,,,} <-- these attributes are dependent on the Key
{Key,TransactionType} -> {ccNum,ccExp,checkNum} <-- these attributes are dependent on a superkey

So my guess is that You are at least in BCNF.

Post the table structure if You want to.


rockmoose
Go to Top of Page

byrmol
Shed Building SQL Farmer

1591 Posts

Posted - 2005-07-05 : 18:49:45
>>I'm just curious what normalization rule is being violated then?

Without the TransactionType table, almost certainly 3NF and 2NF

>>{Key,TransactionType} -> {ccNum,ccExp,checkNum} <-- these attributes are dependent on a superkey

I reckon that breaks 3NF (Mutual independance seems to be violated)

DavidM

A front-end is something that tries to violate a back-end.
Go to Top of Page

rockmoose
SQL Natt Alfen

3279 Posts

Posted - 2005-07-06 : 04:14:49
Oh dear, I'm so confused

Yes, I can relate to the mutual independence breach.

But then again we don't have transitive dependency:
.....Key -> TransactionType
.....TransactionType -> {ccNum,ccExp,checkNum}

Or do we ?

We do have FD on the superkey
.....(Key,TransactionType) -> {ccNum,ccExp,checkNum}

Is that transitive ?


Given the relations, which projections can be taken, to properly normalize the schema ?
I have tried below, but there are probably other (better?) ways.
(maybe there is a FD ccNum -> ccExp as well, but we can overlook that)

Schemas with FD's written out
--------------------------------------------------------------
SCHEMA1 (Which normal forms does it break and Why?)
--------------------------------------------------------------
R0(TransactionType)
PK(TransactionType)

R(Key,TransactionType,Date,Amount,ccNum,ccExp,checkNum)
PRIMARY KEY(Key)
FOREIGN KEY(TransactionType) REFERENCES R0
Key -> TransactionType
Key -> Date
Key -> Amount
{Key,TransactionType} -> ccNum
{Key,TransactionType} -> ccExp
{Key,TransactionType} -> checkNum

--------------------------------------------------------------
SCHEMA2 (R is projected into R1+R2+R3) (Is this 3NF?, are there other better ways?)
--------------------------------------------------------------
R0(TransactionType)
PK(TransactionType)

R1(Key,Date,Amount)
PRIMARY KEY(Key)
Key -> Date
Key -> Amount

R2(Key,TransactionType,ccNum,ccExp)
PRIMARY KEY(Key)
FOREIGN KEY(Key) REFERENCES R1
FOREIGN KEY(TransactionType) REFERENCES R0
CHECK(TransactionType = 'CreditCard')
Key -> TransactionType
Key -> ccNum
Key -> ccExp

R3(Key,TransactionType,checkNum)
PRIMARY KEY(Key)
FOREIGN KEY(Key) REFERENCES R1
FOREIGN KEY(TransactionType) REFERENCES R0
CHECK(TransactionType = 'Check')
Key -> TransactionType
Key -> checkNum



DEFINITIONS OF 3NF, different sources.
quote:
"http://en.wikipedia.org/wiki/Database_normalization"
Third normal form
Third normal form (or 3NF) requires that there are no non-trivial functional dependencies of non-key attributes on something other than a superset of a candidate key.
A relation is in 3NF if none of the non-Primary Key attributes are a fact about any other non-Primary Key attribute.
Another way of saying this is that all non-key attributes are mutually independent (i.e. there should not be transitive dependencies).


quote:
"Introduction to Databse Systems" 6th ed. C.J. Date
Third Normal Form (even more formal definition): A relation is in third normal
form(3NF) if and only of, for all time, each tuple consists of a primary key value
that identifies some entity, together with a set of zero or more mutually indepen-
dent attribute values that describe that entity in some way.

Third Normal Form (definition assuming only one candidate key, which is thus
the primary key): A relation is in 3NF if and only if it is in 2NF and every nonkey
attribute is nontransitively dependent on the primary key. ("No transitive depend-
encies" implies no mutual dependencies, in the sense of that term explained at the
beginning of this section.)

  • Two or more attributes are mutually independent if none of them is functionally
    dependent on any combination of the others. Such independence implies that each
    such attribute can be updated independently of all the rest.



quote:
"Fundamentals of Database Systems" 4th ed. Elmasri,Navathe
Definition. A relation schema R is in third normal form (3NF) if, whenever a
nontrivial functional dependency X->A holds in R, either
(a) X is a superkey of R, or
(b) A is a prime attribute of R.


rockmoose
Go to Top of Page

byrmol
Shed Building SQL Farmer

1591 Posts

Posted - 2005-07-06 : 05:28:10
It's the TransactionType attribute that's screwing it up.(SCHEMA 1)
The mutual dependance is the fact the if the non-key attribute (TransactionType) is updated, then the other 3 non-key attributes need to be updated as well if the predicate is to be satisfied.

If you drop that attribute all together (SCHEMA 2) we are left with the relation istelf defining the transaction type.

Transaction (Key, Date, Amount)
CreditCardTransaction(Key, ccNum,ccExp)
ChequeTransaction(Key, checkNum)

In 1 to 0 | 1 FK's...

Just like Michael suggested.
It is these types of modelling scenario's where views come into there own for both data integrity and middle-tier intergration.

Physically, we main gain some SELECT advantage with the TransactionType column tacked on to all the tables but that's the posters call..

DavidM

A front-end is something that tries to violate a back-end.
Go to Top of Page

rockmoose
SQL Natt Alfen

3279 Posts

Posted - 2005-07-06 : 06:48:00
The "superset of a candidate key" definition got me.
And that definition still somewhat confuses me.

And, yes, the TransactionType relation (+ attribute) is redundant in SCHEMA 2,
because the relations define the type.

So if we have this relation (no TransactionType table as suggested by Eric(poster) once):

Transaction(Key,Date,Amount,ccNum,ccExp,checkNum)
.....primary key(Key)
.....check(either {ccNum,ccExp} or checkNum filled in)

Did You say that it violates 2NF ?, How so?
ccNum,ccExp,checkNum are not mutually independent, so 3NF.


Sorry for being such a dumbass today...

rockmoose
Go to Top of Page

stephe40
Posting Yak Master

218 Posts

Posted - 2005-07-06 : 09:56:33
quote:
Originally posted by rockmoose
.....check(either {ccNum,ccExp} or checkNum filled in)



Don't forget that if all three are empty, then it would be a cash transaction.

- Eric
Go to Top of Page

stephe40
Posting Yak Master

218 Posts

Posted - 2005-07-06 : 10:18:38
Here is them part of my schema that we are discussing... FWIW


CREATE TABLE [dbo].[guests] (
[guestID] [int] IDENTITY (1000, 1) NOT NULL ,
[firstName] [varchar] (100) ,
[lastName] [varchar] (100) ,
[middleName] [varchar] (50) ,
[address1] [varchar] (200) ,
[address2] [varchar] (200)
(most columns removed to shorten this up)
) ON [PRIMARY]
GO

CREATE TABLE [dbo].[reservations] (
[resID] [int] IDENTITY (1, 1) NOT NULL ,
[notes] [varchar] (5000) ,
[guestID] [int] NOT NULL ,
[yearID] [int] NOT NULL ,
[pending] [bit] NOT NULL ,
[dateAdded] [datetime] NULL
) ON [PRIMARY]
GO

CREATE TABLE [dbo].[transactions] (
[transID] [int] IDENTITY (1, 1) NOT NULL ,
[payTypeID] [int] NOT NULL ,
[resID] [int] NOT NULL ,
[amount] [numeric](18, 2) NOT NULL ,
[numbers] [varchar] (50) ,
[ccExp] [char] (4) ,
[transDate] [datetime] NOT NULL
) ON [PRIMARY]
GO

CREATE TABLE [dbo].[paymentTypes] (
[payTypeID] [int] IDENTITY (1, 1) NOT NULL ,
[payTypeDesc] [varchar] (50)
) ON [PRIMARY]
GO

-- PKs....... --

ALTER TABLE [dbo].[guests] ADD
CONSTRAINT [PK_guests] PRIMARY KEY CLUSTERED
(
[guestID]
) WITH FILLFACTOR = 90 ON [PRIMARY]
GO

ALTER TABLE [dbo].[reservations] ADD
CONSTRAINT [PK_reservations] PRIMARY KEY CLUSTERED
(
[resID]
) WITH FILLFACTOR = 90 ON [PRIMARY]
GO

ALTER TABLE [dbo].[transactions] ADD
CONSTRAINT [PK_transactions] PRIMARY KEY CLUSTERED
(
[transID]
) WITH FILLFACTOR = 90 ON [PRIMARY]
GO

ALTER TABLE [dbo].[paymentTypes] ADD
CONSTRAINT [PK_paymentTypes] PRIMARY KEY CLUSTERED
(
[payTypeID]
) WITH FILLFACTOR = 90 ON [PRIMARY]
GO


-- Check Constraints .......... --


ALTER TABLE [dbo].[reservations] ADD

CONSTRAINT [FK_reservations_guests] FOREIGN KEY
(
[guestID]
) REFERENCES [dbo].[guests] (
[guestID]
) ON DELETE CASCADE ON UPDATE CASCADE
GO

ALTER TABLE [dbo].[transactions] ADD
CONSTRAINT [FK_transactions_paymentTypes] FOREIGN KEY
(
[payTypeID]
) REFERENCES [dbo].[paymentTypes] (
[payTypeID]
) ON DELETE CASCADE ON UPDATE CASCADE ,
CONSTRAINT [FK_transactions_reservations] FOREIGN KEY
(
[resID]
) REFERENCES [dbo].[reservations] (
[resID]
) ON DELETE CASCADE ON UPDATE CASCADE
GO




As you can see, at this point, I have a payment types table, and a transactions table which has a FK from the payment types table. I also have the fields "numbers" "ccExp." I plan to store both credit card numbers and check numbers in the "numbers" field. The "ccExp" field will have a value it in when its a credit transaction, and be blank when its a check transaction. Both fields, "numbers" and "ccExp" will be empty when its a cash transaction.

My logic for storing both cc numbers and check numbers in the "numbers" field goes like this. If I had seperate fields for each, one for cc numbers and one for check numbers, and then a new payment type is added, lets say we now accept paypal, there would be no logical place to store a paypal confirmation number. With the field just named "numbers" that number could go there and no database modification would be nessary.

Again I am not 100% happy with this design. But I think its probably the simplest to comprehend. Which may pay off in the long run when I die and someone else has to take over.


- Eric
Go to Top of Page

Michael Valentine Jones
Yak DBA Kernel (pronounced Colonel)

7020 Posts

Posted - 2005-07-06 : 11:49:41
I don't like the name NUMBERS for the column bacause it is too vague. It is really something like PAYMENT_SOURCE_ACCOUNT_NUMBER. NUMBERS is also misleading because it is actually a varchar(50) column.

I dislike overloading a column with multiple types of data. My experience is that I always find a reason to regret it later. You will probably find that each type of trasaction requires its own set of data, for example, bank routing number and account number for a check. I think it is better to plan that you will add columns for new payment types as needed, or add new tables to handle the specific info for each payment type.


CODO ERGO SUM
Go to Top of Page

stephe40
Posting Yak Master

218 Posts

Posted - 2005-07-06 : 13:00:25
Yes I agree that "numbers" is a little vague. But the point here is that there should not be any database modifications required if a new payment type is added. Thats the whole point of having the seperate payment types table.

Option 1: have a seperate field in the transaction table for each payment type. And whenever a new payment type is needed a different field is added to track whatever info it needs. As some point there would be a buch of field that are null for each row.

Option 2: Have a seperate table for each payment type. The transaction table would then have multiple child tables. So to get a report of all transactions for the current day there would need to be miltiple joins to for a data set that is identical to option 1 for reporting. This would then also require a new table evertime a new payment type is added.

Is the overhead of modifying the database, (either adding columns or adding tables), less than overloading one column?

- Eric
Go to Top of Page

byrmol
Shed Building SQL Farmer

1591 Posts

Posted - 2005-07-06 : 20:24:03
>>But the point here is that there should not be any database modifications required if a new
>>payment type is added.

Just use a big string field and stuff every thing into it...credit card numbers, expiry date, cheque, pay pal.. anything you want... I am sure the front end will love that.. :-)

Will the front end have to change when a new payment type is added? If it does then the maintenance side of the argument is mute..

>>So to get a report of all transactions for the current day there would need to be miltiple
>>joins to for a data set

How many times a day does this report get run? Once? This is the last thing you should be worried about at this stage.. Concentrate on the data and making it bulletproof to mistakes..

I am yet to come across a client who willing sacrifices a "slow" truth for a "fast" lie.

Whatever design you choose, I STRONGLY recommend using views for (at the very least) data integrity of the different payment types.

DavidM

A front-end is something that tries to violate a back-end.
Go to Top of Page

stephe40
Posting Yak Master

218 Posts

Posted - 2005-07-07 : 11:03:56
quote:
Originally posted by byrmol


Just use a big string field and stuff every thing into it...credit card numbers, expiry date, cheque, pay pal.. anything you want... I am sure the front end will love that.. :-)

Will the front end have to change when a new payment type is added? If it does then the maintenance side of the argument is mute..

How many times a day does this report get run? Once? This is the last thing you should be worried about at this stage.. Concentrate on the data and making it bulletproof to mistakes..

I am yet to come across a client who willing sacrifices a "slow" truth for a "fast" lie.

Whatever design you choose, I STRONGLY recommend using views for (at the very least) data integrity of the different payment types.

DavidM

A front-end is something that tries to violate a back-end.




I understand your point. The front end is yet to be designed, we have a few preliminary mockups but nothing is created for real yet. I think the interface could be easily designed to not require an update if a payment type is added. That’s why the field was just called ‘numbers’ so that when someone adds a payment type, there is a field for whatever number they want. But I do see your point. Because what if a new payment type requires two numbers. Then in that case we would need to add a column and modify the interface. Double whammy.

This is why I said that I am not 100% happy with the current setup. I am defiantly not opposed to changing it to a better setup if one comes along.

In regard to the report I mentioned. You were correct, the report would only be run once a day, maybe twice. But is not a real valid point in this debate.

At this point I don’t think I have seen or thought of any “bulletproof” solution. I’ll keep thinking.


- Eric
Go to Top of Page

stephe40
Posting Yak Master

218 Posts

Posted - 2005-07-07 : 11:08:21
Here is another option that I came up with but it is not 100% bulletproof.

Tables

paymentTypes (payTypeID int, payTypeDescrip varchar(50))
transactions (transID int, payTypeID int, transDate, datetime, amount money)
extendedPaymentProperties (payPropID int, payPropName varchar(50))
extendedPaymentPropertyValues (transID int, payPropID int, value varchar(50))
Example Data

extendedPaymentProperties
payPropID payPropName
1 Credit Card Number
2 Credit Card Exp
3 Check Number
4 PayPal Confirmation Number
5 Some other useless number

paymentTypes
payTypeID payTypeDesc
1 Credit
2 Check
3 Cash
4 Paypal

transactions
transID payTypeID transDate amount
1001 1 1/1/05 1:00 AM 50.34
1002 4 1/1/05 1:11 AM 123.13
1003 2 1/1/05 1:34 AM 200.00
1004 3 1/1/05 1:35 AM 123.34

Then extendedPaymentPropertyValues would look like this.

transID payPropID value
1001 1 1234123412341234
1001 2 06/08
1002 4 123AUD28D902KL
1003 3 4321


The problem with this design is the datatype of “value” in the extendedPaymentPropertyValues table. What if for some reason there needs to be another date and time stored. That date value then would need to be stored as a character. What do you guys think about this setup?

I am very interested in your opinions because I use this same type of design in another part of the database. We needed a way of storing start and stop times for certain properties, like costs and stuff. Mostly because room rates change as time goes on.

Anyway, TIA


- Eric
Go to Top of Page

byrmol
Shed Building SQL Farmer

1591 Posts

Posted - 2005-07-07 : 18:50:58
Eric,

The final design is referred to as a EVA (Enitity, Value, Attribute) design and is very hard to maintain well, due primarily to poor type control. Don't go there...

You have got to keep remembering the difference between your logical design and the physcially implemention of it. Don't even think about SQL Server when designing your logical model.

Ideally, PaymentType would form a single attribute with the various paymenttypes being inherited from a basetype.

eg.

Transaction (TranID INT, DateOf DATE, Amount MONEY, TransactionData TransactionType)

abstract TransactionType (TypeName VARCHAR(10) = 'Base')
CashType: TransactionType (override TypeName ='Cash')
CreditType: TransactionType(override TypeName ='Credit', Credit# INT, Expiry DATE)
etc...

You still have to alter the DBMS and UI when new types arrive but I reckon it could be done it about 10 minutes flat..

So... considering type support is limited in our physcially DBMS, we have to innovate. Keep remembering the logical model hasn't changed, only how the hell we are going to stuff into SQL Server...

Hence the idea of using tables as the different types of transactions... Wrap a few views around the whole thing, and you should come very close to your logical model..

A simple factory pattern in the middle tier handles these situations very well in my experience and makes modifications almost trivial....

DavidM

A front-end is something that tries to violate a back-end.
Go to Top of Page

stephe40
Posting Yak Master

218 Posts

Posted - 2005-07-08 : 10:41:54
Even after all this I still don't know what to do. I'm having trouble actually visualizing how David's suggestion would be layed out. I guess Ill keep debating this in my head and try to come up with something.

- Eric
Go to Top of Page

stephe40
Posting Yak Master

218 Posts

Posted - 2005-07-11 : 14:39:28
So going with Davids suggestion the tables would look like...

paymentTypes (payTypeID PK, payTypeDesc)
transactions (transID PK, payTypeID FK, amount, transDate)
creditCards(ccID PK, ccNumber, ccExp, transID FK)
checks (checkID PK, checkNum, transID FK)

Am I understanding it right?

- Eric
Go to Top of Page

byrmol
Shed Building SQL Farmer

1591 Posts

Posted - 2005-07-11 : 20:32:35
>>Am I understanding it right?
Partially...The transID becomes the PK and FK in the creditCards and checks table.

Please tell me that payTypeID is NOT planning on being an identity column.. I could rant on for hours about blindly showing identity column anywhere...

I am working on similar designs at the moment so I will give a working example of the pattern I use for this...

First up the physcial schema...

create schema authorization dbo
create table paymentTypes (payTypeID varchar(15) primary key
, payTypeDesc varchar(255) not null default(''))
create table transactionBase (transID INT IDENTITY(1,1) primary key check(transid > 0)
, payTypeID varchar(15) not null, amount money not null check(amount > 0)
, transDate datetime not null default(getdate())
, foreign key (payTypeID) references paymentTypes (payTypeID))
create table transactionCreditCard(transID INT primary key default(IDENT_CURRENT('transactionBase'))
, ccNumber varchar(15)not null check(len(ccNumber) > 0) , ccExp datetime not null
, foreign key (transID) references transactionBase (transID))
create table transactionCheck (transID INT primary key default(IDENT_CURRENT('transactionBase'))
, checkNum varchar(35) not null
, foreign key (transID) references transactionBase (transID))


The only "tricky" part of that schema is the really cool default for the transID in the "sub type" tables.. We'll use this later on...

Let's try and make it bullet proof...

The WITH CHECK OPTION enforces any constraints defined in the select statement of the view...

create view transaction_Cash
AS
select transID, payTypeID, amount, transDate
from dbo.transactionbase
WHERE payTypeID = 'Cash'
with check option

create view transaction_Cheque_CONSTRAINT
AS
select tb.transID, tb.payTypeID, tb.amount, tb.transDate
from dbo.transactionbase tb
WHERE payTypeID = 'Cheque'
with check option

create view transaction_CreditCard_CONSTRAINT
AS
select tb.transID, tb.payTypeID, tb.amount, tb.transDate
from dbo.transactionbase tb
WHERE payTypeID = 'Credit Card'
with check option

create view transaction_Cheque
AS
select tb.transID, tb.payTypeID, tb.amount, tb.transDate, tc.checkNum
from dbo.transactionbase tb
inner join dbo.transactionCheck tc on tc.transID = tb.transID
WHERE payTypeID = 'Cheque'

create view transaction_CreditCard
AS
select tb.transID, tb.payTypeID, tb.amount, tb.transDate, tc.ccNumber, tc.ccExp
from dbo.transactionBase tb
inner join dbo.transactionCreditCard tc on tc.transID = tb.transID
WHERE tb.payTypeID = 'Credit Card'


The "Cash" transaction type only requires the one view (it is already updateable) but all "sub types" require 2 views and a INSTEAD OF trigger to be useful...



create trigger trg_transaction_Cheque_INSERT
on transaction_Cheque
instead of insert
as
insert dbo.transaction_Cheque_CONSTRAINT ( payTypeID, amount, transDate)
select paytypeid, amount, transdate
from inserted i
insert dbo.transactionCheck (checkNum)
select checkNum
from inserted i
go
create trigger trg_transaction_CreditCard_INSERT
on transaction_CreditCard
instead of insert
as

insert dbo.transaction_CreditCard_CONSTRAINT ( payTypeID, amount, transDate)
select paytypeid, amount, transdate
from inserted i
insert dbo.transactionCreditCard ( ccNumber, ccExp)
select ccNumber, ccExp
from inserted i
go


The only issue is that these triggers will fail on multi-row inserts... The default defined only copes with single row insertion. Notice that we insert into the base "_CONSTRAINT" view to ensure that the right type is entered

We are left with 3 views that the front-end gang can play with all they like..

insert paymentTypes (payTypeID, payTypeDesc)
select 'Cash', ''
union all
select 'Cheque', ''
union all
select 'Credit Card', ''
go
insert dbo.transaction_cash (payTypeID, amount, transDate)
values ('Cash', RAND() * 1000, getdate())
insert dbo.transaction_Cheque (transID, payTypeID, amount, transDate, checkNum)
values (0, 'Cheque', RAND() * 1000, getdate(), 'd2345345345')
insert dbo.transaction_CreditCard (transID, payTypeID, amount, transDate, ccNumber, ccExp)
values (0, 'Credit Card', RAND() * 1000, getdate(), '123213', '01/05/2002')


Finally you could create a "report" view..

create view transaction_detailed
as
select transID, payTypeID, amount, transDate, 'n/a' as details
from dbo.transaction_Cash
union all
select transID, payTypeID, amount, transDate, checkNum
from dbo.transaction_Cheque
union all
select transID, payTypeID, amount, transDate, ccNumber + '(' + CAST(ccExp as varchar(20)) + ')' as details
from dbo.transaction_CreditCard
go
select * from transaction_cash
select * from transaction_cheque
select * from transaction_CreditCard
select * from transaction_detailed

The whole point is data integrity and 20 lines in the DBMS is worth hundreds of lines elsewhere...

There is nothing stopping you using a single stored proc that contains IF logic to INSERT into the right view, thus giving the UI guys a single proc to insert into...

I hope this helps...

DavidM

A front-end is something that tries to violate a back-end.
Go to Top of Page
    Next Page

- Advertisement -