3

私はPDOを初めて使用し、現在すべてのクエリを書き直そうとしています。ループ内で記述されているため、書き換えに問題があるクエリの1つは次のクエリです。

$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);

この方法ではあまり運がありません。「無効なパラメータ番号:バインドされた変数の数がトークンの数と一致しません」というエラーメッセージが表示され続けます

何か案は?

ありがとう、

ランス

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

書き換えにいくつかのエラーがあります。

  • クエリの作成中に、prepare / bind/executeを数回呼び出しています。クエリ文字列が完全に構築された後、prepareを1回だけ呼び出し、クエリ構築後にbind+executeを呼び出す必要があります。
  • ループのすべての反復で、クエリに1つまたは2つの(j == 0の場合)パラメーターを追加しますが、ループごとに1つだけバインドしようとします。そのため、数値は合計されません。

一般に、パラメトリッククエリを使用するには、次の構造に従う必要があります。

  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 に答える