PHP Python Java Using Prepared Statements and Placeholders in Queries

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

PHP provides no support for placeholders. See Recipe 2.9 t o find out how t o const ruct queries t hat refer t o dat a values t hat m ay cont ain special charact ers. Or see Recipe 2.10 , w hich develops a class- based int erface for PHP t hat em ulat es placeholders.

2.7.6 Python

Pyt hons MySQLdb m odule im plem ent s t he concept of placeholders by using form at specifiers in t he query st ring. To use placeholders, invoke t he execute m et hod w it h t w o argum ent s: a query st ring cont aining form at specifiers, and a sequence cont aining t he values t o be bound t o t he query st ring. The following query uses placeholders t o search for records where t he num ber of cat s is less t han 2 and t he favorit e color is green: try: cursor = conn.cursor cursor.execute SELECT FROM profile WHERE cats s AND color = s, \ 2, green for row in cursor.fetchall : print row print d rows were returned cursor.rowcount cursor.close except MySQLdb.Error, e: print Oops, the query failed print e I f you have only a single value val t o bind t o a placeholder, you can writ e it as a sequence using t he synt ax val , . The following UPDATE st at em ent dem onst rat es t his: try: cursor = conn.cursor cursor.execute UPDATE profile SET cats = cats+1 WHERE name = s, \ Fred, print d rows were updated cursor.rowcount except MySQLdb.Error, e: print Oops, the query failed print e Som e of t he Pyt hon DB- API driver m odules support several form at specifiers such as d for int egers and f for float ing-point num bers . Wit h MySQLdb, you should use a placeholder of s t o form at all dat a values as st rings. MySQL will perform t ype conversion as necessary. I f you want t o place a lit eral charact er int o t he query, use in t he query st ring. Pyt hons placeholder m echanism provides quot es around dat a values as necessary when t hey are bound t o t he query st ring, so you need not add t hem yourself.

2.7.7 Java

JDBC provides support for placeholders if you use prepared st at em ent s rat her t han regular st at em ent s. Recall t hat t he process for issuing regular st at em ent s is t o creat e a Statement obj ect and t hen pass t he query st ring t o one of t he query- issuing funct ions executeUpdate , executeQuery , or execute . To use a prepared st at em ent inst ead, creat e a PreparedStatement obj ect by passing a query st ring cont aining ? placeholder charact ers t o your connect ion obj ect s prepareStatement m et hod. Then bind your dat a values t o t he st at em ent using set XXX m et hods. Finally, execut e t he st at em ent by calling executeUpdate , executeQuery , or execute wit h an em pt y argum ent list . Here is an exam ple t hat uses executeUpdate t o issue a DELETE query: PreparedStatement s; int count; s = conn.prepareStatement DELETE FROM profile WHERE cats = ?; s.setInt 1, 2; bind a 2 to the first placeholder count = s.executeUpdate ; s.close ; close statement System.out.println count + rows were deleted; For a query t hat ret urns a result set , t he process is sim ilar, but you use executeQuery inst ead: PreparedStatement s; s = conn.prepareStatement SELECT id, name, cats FROM profile + WHERE cats ? AND color = ?; s.setInt 1, 2; bind 2 and green to first and second placeholders s.setString 2, green; s.executeQuery ; ... process result set here ... s.close ; close statement The set XXX m et hods t hat bind dat a values t o queries t ake t wo argum ent s: a placeholder posit ion beginning wit h 1, not 0 and t he value t o be bound t o t he placeholder. The t ype of t he value should m at ch t he t ype in t he set XXX m et hod nam e. For exam ple, you should pass an int eger value t o setInt , not a st ring. Placeholder charact ers need no surrounding quot es in t he query st ring. JDBC supplies quot es as necessary when it binds values t o t he placeholders.

2.8 Including Special Characters and NULL Values in Queries