That's a tough one. Even with individual 800 numbers, you're not guaranteed 100% accuracy, since someone may call the wrong number by mistake (for example, with a block of numbers a customer could be one digit off and still get through).
The most accurate solution is having them enter a member ID. My bank requires an ID, then does a lookup to see if my ANI matches a phone number associated with my account and allows me to proceed without more detailed identification when it finds a match. Something like that would probably be the best practice.
If you have to use the DNIS to match a particular customer, some folks use a table set up in IA to hold the information, then use a custom handler in CustomIncomingCall.ihd to look up the DNIS in the table and populate an attribute on the call to show the caller's identity later in the system.
Otherwise, for slower access (across the network rather than in memory on the IC server) you can use a database to store the info. You could set up an Attendant profile which matches on the DNIS (put in a range of DNIS for those customers who get a common menu, or one profile per customer if you want to get really complicated). Then use a DB Query operation to look up the customer info from a database and set the attribute(s) on the call.
Lots of options. The best and most accurate being to have the customer enter a member ID when they hit the menu.