Problem Solution Discussion Issue Individual Queries Construct a Hash from the Entire Lookup Table

{ valid = 0; value contains an invalid element last; } } } return valid; } For bulk t est ing, const ruct a hash from t he legal SET m em bers. The procedure is t he sam e as for producing a hash from ENUM elem ent s: my ref = get_enumorset_info dbh, tbl_name, col_name; my members; foreach my member {ref-{values}} { convert hash key to consistent case; SET isnt case sensitive members{lc member} = 1; } To validat e a given input value against t he SET m em ber hash, convert it t o t he sam e let t ercase as t he hash keys, split it at com m as t o get a list of t he individual elem ent s of t he value, t hen check each one. I f any of t he elem ent s are invalid, t he ent ire value is invalid: valid = 1; assume valid until we find out otherwise foreach my elt split ,, lc val { if exists members{elt} { valid = 0; value contains an invalid element last; } } Aft er t he loop t erm inat es, valid is t rue if t he value is legal for t he SET colum n, and false ot herwise. Em pt y st rings are always legal SET values, but t his code doesnt perform any special-case t est for an em pt y st ring. No such t est is necessary, because in t hat case t he split operat ion ret urns an em pt y list , t he loop never execut es, and valid rem ains t rue.

10.29 Validation Using a Lookup Table

10.29.1 Problem

You need t o check values t o m ake sure t heyre list ed in a lookup t able.

10.29.2 Solution

I ssue queries t o see if t he values are in t he t able. But t he way you do t his depends on t he num ber of input values and on t he size of t he t able.

10.29.3 Discussion

To validat e input values against t he cont ent s of a lookup t able, you can use t echniques som ewhat sim ilar t o t hose shown in Recipe 10.28 on checking ENUM and SET colum ns. However, whereas ENUM and SET colum ns are lim it ed t o a m axim um of 65,536 and 64 m em ber values respect ively, a lookup t able can have an essent ially unlim it ed num ber of values. You m ay not want t o read t hem all int o m em ory. Validat ion of input values against t he cont ent s of a lookup t able can be done several ways, as illust rat ed in t he following discussion. The t est s shown in t he exam ples perform com parisons against values exact ly as t hey are st ored in t he lookup t able. To perform case- insensit ive com parisons, rem em ber t o convert all values t o a consist ent let t ercase.

10.29.4 Issue Individual Queries

For one- shot operat ions, you can t est a value by checking whet her it s list ed in t he lookup t able. The following query ret urns t rue nonzero a value t hat is present and false ot herwise: valid = dbh-selectrow_array SELECT COUNT FROM tbl_name WHERE val = ?, undef, val; This kind of t est m ay be suit able for purposes such as checking a value subm it t ed in a web form , but is inefficient for validat ing large dat aset s. I t has no m em ory for t he result s of previous t est s for values t hat have been seen before; consequent ly, youll end up issuing a query for every single input value.

10.29.5 Construct a Hash from the Entire Lookup Table

I f youre going t o perform bulk validat ion of a large set of values, it s m ore efficient t o pull t he lookup values int o m em ory, save t hem in a dat a st ruct ure, and check each input value against t he cont ent s of t hat st ruct ure. Using an in- m em ory lookup avoids t he overhead of running a query for each value. First , run a query t o ret rieve all t he lookup t able values and const ruct a hash from t hem : my members; hash for lookup values my sth = dbh-prepare SELECT val FROM tbl_name; sth-execute ; while my val = sth-fetchrow_array { members{val} = 1; } Then check each value by perform ing a hash key exist ence t est : valid = exists members{val}; This reduces t he dat abase t raffic t o a single query. However, for a large lookup t able, t hat m ay st ill be a lot of t raffic, and you m ay not want t o hold t he ent ire t able in m em ory. Performing Lookups with Other Languages The exam ple shown here for bulk t est ing of lookup values uses a Perl hash t o det erm ine whet her or not a given value is present in a set of values: valid = exists members{val}; Sim ilar dat a st ruct ures exist for ot her languages. I n PHP, you can use an associat ive array and perform a key lookup like t his: valid = isset members[val]; I n Pyt hon, use a dict ionary and check input values using t he has_key m et hod: valid = members.has_key val For lookups in Java, use a HashMap and t est values wit h t he containsKey m et hod: valid = members.containsKey val; The t ransfer direct ory of t he recipes dist ribut ion cont ains som e sam ple code for lookup operat ions in each of t hese languages.

10.29.6 Use a Hash as a Cache of Already-Seen Lookup Values