Perl Using Prepared Statements and Placeholders in Queries

One of t he benefit s of prepared st at em ent s and placeholders is t hat param et er binding operat ions aut om at ically handle escaping of charact ers such as quot es and backslashes t hat you have t o worry about yourself if you put t he dat a values int o t he query yourself. This can be especially useful if youre insert ing binary dat a such as im ages int o your dat abase, or using dat a values wit h unknown cont ent such as input subm it t ed by a rem ot e user t hrough a form in a web page. Anot her benefit of prepared st at em ent s is t hat t hey encourage st at em ent reuse. St at em ent s becom e m ore generic because t hey cont ain placeholders rat her t han specific dat a values. I f youre execut ing an operat ion over and over, you m ay be able t o reuse a prepared st at em ent and sim ply bind different dat a values t o it each t im e you execut e it . I f so, you gain a perform ance benefit , at least for dat abases t hat support query planning. For exam ple, if a program issues a part icular t ype of SELECT st at em ent several t im es while it runs, such a dat abase can const ruct a plan for t he st at em ent , t hen reuse it each t im e, rat her t han rebuilding t he plan over and over. MySQL doesnt build query plans, so you dont get any perform ance boost from using prepared st at em ent s. However, if you port a program t o a dat abase t hat does use query plans, youll gain t he advant age of prepared st at em ent s aut om at ically if youve writ t en your program from t he out set t o use t hem . You wont have t o convert from non- prepared st at em ent s t o enj oy t hat benefit . A t hird benefit is t hat code t hat uses placeholder- based queries can be easier t o read, alt hough t hat s som ewhat subj ect ive. As you read t hrough t his sect ion, you m ight com pare t he queries used here wit h t hose from t he previous sect ion t hat did not use placeholders, t o see which you prefer.

2.7.4 Perl

To use placeholders in DBI script s, put a ? in your query st ring at each locat ion where you want t o insert a dat a value, t hen bind t he values t o t he query. You can bind values by passing t hem t o do or execute , or by calling a DBI m et hod specifically int ended for placeholder subst it ut ion. Wit h do , pass t he query st ring and t he dat a values in t he sam e call: my count = dbh-do UPDATE profile SET color = ? WHERE name = ?, undef, green, Mara; The argum ent s aft er t he query st ring should be undef follow ed by t he dat a values, one value for each placeholder. The undef argum ent t hat follows t he query st ring is a hist orical art ifact , but m ust be present . Wit h prepare plus execute , pass t he query st ring t o prepare t o get a st at em ent handle. Then use t hat handle t o pass t he dat a values via execute : my sth = dbh-prepare UPDATE profile SET color = ? WHERE name = ?; my count = sth-execute green, Mara; You can use placeholders for SELECT st at em ent s, t oo. The following query looks for records having a name value t hat begins wit h M : my sth = dbh-prepare SELECT FROM profile WHERE name LIKE ?; sth-execute M; while my ref = sth-fetchrow_hashref { print id: ref-{id}, name: ref-{name}, cats: ref-{cats}\n; } sth-finish ; A t hird way of binding values t o placeholders is t o use t he bind_param call. I t t akes t wo argum ent s, a placeholder posit ion and a value t o be bound t o t he placeholder at t hat posit ion. Placeholder posit ions begin wit h 1, not 0. The previous t wo exam ples can be rewrit t en t o use bind_param as follow s: my sth = dbh-prepare UPDATE profile SET color = ? WHERE name = ?; sth-bind_param 1, green; sth-bind_param 2, Mara; my count = sth-execute ; my sth = dbh-prepare SELECT FROM profile WHERE name LIKE ?; sth-bind_param 1, M; sth-execute ; while my ref = sth-fetchrow_hashref { print id: ref-{id}, name: ref-{name}, cats: ref-{cats}\n; } sth-finish ; No m at t er which m et hod you use for placeholders, dont put any quot es around t he ? charact ers, not even for placeholders t hat represent st rings. DBI adds quot es as necessary on it s own. I n fact , if you do put quot es around t he placeholder charact er, DBI will int erpret it as t he lit eral st ring const ant ? , not as a placeholder. The high- level ret rieval m et hods such as selectrow_array and selectall_arrayref can be used wit h placeholders, t oo. Like t he do m et hod, t he argum ent s are t he query st ring and undef , followed by t he dat a values t o be bound t o t he placeholders t hat occur in t he query st ring. Heres an exam ple: my ref = dbh-selectall_arrayref SELECT name, birth, foods FROM profile WHERE id ? AND color = ?, undef, 3, green; Generating a List of Placeholders When you want t o use placeholders for a set of dat a values t hat m ay vary in size, you m ust const ruct a list of placeholder charact ers. For exam ple, in Perl, t he following st at em ent creat es a st ring consist ing of n placeholder charact ers separat ed by com m as: str = join ,, ? x n ; The x repet it ion operat or, when applied t o a list , produces n copies of t he list , so t he join call j oins t hese list s t o produce a single st ring cont aining n com m a- separat ed inst ances of t he ? charact er. This is handy when you want t o bind an array of dat a values t o a list of placeholders in a query st ring, because t he size of t he array indicat es how m any placeholder charact ers are needed: str = join ,, ? x values; Anot her m et hod of generat ing a list of placeholders t hat is perhaps less crypt ic looks like t his: str = ? if values; str .= ,? for 1 .. values-1; Yet a t hird m et hod is as follows: str = ? if values; for my i = 1; i values; i++ { str .= ,?; } That m et hods synt ax is less Perl- specific and t herefore easier t o t ranslat e int o ot her languages. For exam ple, t he equivalent m et hod in Pyt hon looks like t his: str = if len values 0: str = ? for i in range 1, len values: str = str + ,?

2.7.5 PHP