I'd like to write my PostgreSQL (9.3) SELECT dynamically based on the user's fields filled out in the query form:
$cond = '';
if ($_REQUEST['sel_when_a'] != '')
$cond .= ' AND field_lastmod >= $2';
if ($_REQUEST['sel_when_b'] != '')
$cond .= ' AND field_lastmod <= $3';
$sel = ExecSQLP('SELECT field_value, field_lastmod
FROM my_values
WHERE field_value ILIKE \'%\' || $1 || \'%\'
. $cond .
' ORDER BY node_id;'
, array( $_REQUEST['sel_find'], $_REQUEST['sel_when_a'], $_REQUEST['sel_when_b'] ));
(ExecSQLP is my function to execute an SQL statement with the arguments, based on pg_query_params.)
This is simple and elegant, but I get an error message: Query failed: ERROR: bind message supplies 3 parameters, but prepared statement "" requires 1 if sel_when_a ("after") and sel_when_b ("before") are empty.
I think this shouldn't be an error in PostgreSQL as it doesn't do any bad if an unused parameter is supplied. Can I suppress this error? Othervise how to build the statement with different number of parameters? I have a lot of them, not only the 3 above. It'd be terrible to prepare for the several cases with renumbered parameters if PostgreSQL doesn't allow this.
The documentation: http://www.postgresql.org/docs/9.3/interactive/sql-expressions.html#SQL-EXPRESSIONS-PARAMETERS-POSITIONAL is not very useful for this case.
Thanks for your tips. SQL injection vulnerability is not accepted!
(Perhaps similar to How to handle dynamic number of parameters in querystring when building REST api?, but the relation is not always "equals to a string".)