Bineesh Varghese
Bineesh Varghese

Reputation: 115

PHP PDO Dynamic Query Building

$arr = array();
$from_date = '2015-01-01';
$to_date = '2015-01-31';
$order_no = '25215';
$sql = "SELECT * FROM test";
if(!empty($from_date)&&!empty($to_date))
{
    $sql.=" WHERE txn_date BETWEEN :from_date AND :to_date";
    $arr[] = ":from_date => $from_date";
    $arr[] = ":to_date => $to_date";
    $condition=true;
}
if(!empty($order_no))
{
    if($condition)
    {
       $sql.=" AND ref_number = :order_no";
       $arr[] = ":order_no => $order_no";
    }
    else
    {
       $sql.=" WHERE ref_number = :order_no";
       $arr[] = ":order_no => $order_no";
       $condition=true;
    }
}
$stmt = $db->prepare($sql);
$stmt->execute($arr);
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);

When executing this query shows a warning like

Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: parameter was not defined

what is wrong with it?

Upvotes: 0

Views: 1448

Answers (2)

gvgvgvijayan
gvgvgvijayan

Reputation: 2506

In variable $arr you should replace as like this for all associative index

$arr[':from_date'] = $from_date;
$arr[':to_date'] = $to_date;
$arr[':order_no'] = $order_no;

Also it is good practice to move common code in outer block instead of if/else ladder

if(!empty($order_no))
{
    $arr[':order_no'] = $order_no;
    if($condition)
    {
       $sql.=" AND ref_number = :order_no";
    }
    else
    {
       $sql.=" WHERE ref_number LIKE :order_no";
       $condition=true;
    }
}

As op asked in comment here is the explanation for that

$sql.=" WHERE txn_date BETWEEN :from_date AND :to_date";

Replace this with this one

$sql.=" WHERE date(txn_date) BETWEEN date(:from_date) AND date(:to_date)";

ref_number = :order_no

Instead of the above one type cast it to unsigned integer as like this in both where condition in if/else statement

CONVERT(ref_number,UNSIGNED INTEGER) = :order_no

Upvotes: 2

Honza Haering
Honza Haering

Reputation: 812

Instead of

$arr[] = ":from_date => $from_date";

do

$arr['from_date'] = $from_date;

Read more about php arrays here.

Also, what I would do is:

$sql = "SELECT * FROM test WHERE 1=1";

Then there is no need to test for $condition and just simply concatenate to $sql.

Upvotes: 1

Related Questions