3

我是 PDO 的新手,目前正在尝试重写我的所有查询。我在重写时遇到问题的一个查询是这个,因为它是在循环中编写的:

$search = $_GET['search'];
$code = explode(" ", $search);
$code_count = count($code);

$query = "SELECT * FROM table";

if($search != "")
{
if($code_count == 1)
{
     $query .= " WHERE team LIKE '%".mysql_real_escape_string($search)."%'";
} elseif($code_count > 1)
{   
       for($j=0;$j<$code_count;$j++)
       {
        if($j != 0)
        {
        $query .= " OR "; 
        } else
        {
        $query .= " WHERE team LIKE '%".mysql_real_escape_string($code[$j])."%' OR ";
        }           

                $query .= " team LIKE '%".mysql_real_escape_string($code[$j])."%'";
    }

    $query .= "ORDER BY team ASC";
}
} else
{
$query = "SELECT * FROM table ORDER BY team ASC";
}

$result = mysql_query($query)or die(mysql_error());

使用 PDO,我尝试了以下方法。

$query = "SELECT * FROM table";

if($search != "")
{
if($code_count == 1)
{
     $query .= " WHERE team LIKE ?";

         $stmt = $db->prepare($query);
         $stmt->bindValue(1, "%$search%", PDO::PARAM_STR);
         $stmt->execute();
} elseif($code_count > 1)
{   
       for($j=0;$j<$code_count;$j++)
       {
        if($j != 0)
        {
        $query .= " OR "; 
        } else
        {
        $query .= " WHERE team LIKE ? OR ";
        }           

                $query .= " team LIKE ?";

               $stmt = $db->prepare($query);
               $stmt->bindValue(1, "%$code[$j]%", PDO::PARAM_STR);
              $stmt->execute();
    }

    $query .= "ORDER BY team ASC";
}
} else
{
$query = "SELECT * FROM table ORDER BY team ASC";
}

$result = $stmt->fetchAll(PDO::FETCH_ASSOC);

这种方法运气不好。我不断收到一条错误消息:“nvalid parameter number: number of bound variables does not match number of tokens”

有任何想法吗?

谢谢,

4

3 回答 3

2

当您不自己分配名称时,绑定参数被命名1为。n您需要更改此行:

$stmt->bindValue(1, "%$code[$j]%", PDO::PARAM_STR);

对此:

$stmt->bindValue($j + 1, "%" . $code[$j] . "%", PDO::PARAM_STR);
于 2013-01-17T13:41:08.683 回答
0

由于可以将一组参数传递给PDOStatement::execute()而不是手动绑定每个参数,因此可以极大地简化整个事情:

$code = explode(' ', $_GET['search']);

$stmt = $db->prepare('
  SELECT   *
  FROM     table
  WHERE    FALSE ' . str_repeat(' OR team LIKE ?', count($code)) . '
  ORDER BY team ASC
');

$stmt->execute($code);
于 2013-01-17T13:53:54.843 回答
-1

您的重写中有几个错误:

  • 您在构建查询期间多次调用准备/绑定/执行。您应该只调用一次准备,在您的查询字符串完全构造后,并在查询构造后绑定+执行。
  • 在循环的每次迭代中,您向查询添加一两个 (if j == 0) 参数,但您尝试在每个循环中仅绑定一个 - 所以数字不会相加。

通常,要使用参数查询,您需要遵循以下结构:

  1. 构建您的查询字符串
  2. 准备你的查询字符串
  3. 每次您要运行查询时:
    1. 绑定参数
    2. 执行
    3. 拿来

所以你的代码应该是这样的:

// building query
if($search != "")
{
  $query = 'SELECT * FROM table ';
  if($code_count == 1)
  {
    // note: this if is unneccessary, the loop below would generate a good SQL even for code_count 0 or 1
    $query .= "WHERE team LIKE ?";

  } elseif($code_count > 1)
  {   
    for($j=0;$j<$code_count;$j++)
    {
      if($j != 0)
      {
        $query .= " OR "; 
      } else
      {
        $query .= " WHERE ";
      }           

      $query .= " team LIKE ? ";
    }

    $query .= "ORDER BY team ASC";
}
} else
{
  $query = "SELECT * FROM table ORDER BY team ASC";
}

// preparing

$stmt = $db->prepare($query);

// binding parameters
if($search != '' && $code_count >= 1) {
  for($j=0;$j<$code_count;$j++){
    $stmt->bindValue($j+1, "%".$code[$j]."%", PDO::PARAM_STR);
  }
}

// execute

$stmt->execute();

// fetch

$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
于 2013-01-17T13:49:29.967 回答