0

MySQLクエリは

SELECT CompanyName, RegistrationNumber, VatCode 
FROM 18_6_TransactionPartners 
WHERE (CompanyName = ? OR RegistrationNumber = ? OR VatCode = ?) 

?に置き換え$data_show_existing_recordsます。ただし、最初$data_show_existing_recordsは文字列 (ユーザー入力) の形式です。

最初はそのようなものを作成することにしました$data_show_existing_records = $data_show_existing_records. $data_a[$i]. ','. $data_b[$i]. ','. $data_d[$i]. ',';(これは foreach 内で作成されます。これは、$i0 だけでなく、100 になることもあるためです)

そして、そのような方法で配列に変換します

$data_show_existing_records = substr($data_show_existing_records, 0, -1);

$data_show_existing_records = explode(",", $data_show_existing_records);

ただし、たとえば、CompanyNameユーザーが入力しMy, companyたり、一部の入力を空のままにしたりする場合があります。

そのような場合、エラーが発生しますSQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens。よりも多く$dataの配列があるため?です。

次に、に置き換えることに,しました||は よりも使用されていないため,)。

しかし、これは良い解決策ではないようです。何が良いでしょうか (文字列/ユーザー入力セパレータとして何を使用するか)? 逃げる必要があるかもしれませ,ん(しかし、どのように)?ご意見をお聞かせください

空の入力の見つかったソリューションを更新します。$data_show_existing_records = $data_show_existing_records. "$data_a[$i]". ','. "$data_b[$i]". ','. "$data_d[$i]". ',';

しかし、どうすればいい,ですか?

次回更新

初期クエリ(短縮コード)とクエリ用データの作成

foreach ($num_row_1 as $i => $row) {//$num_row_1 is number of rows in user input
$query_to_show = $query_to_show. 'WHERE (CompanyName = ? OR RegistrationNumber = ? OR VatCode = ?) ';
$data_show_existing_records = $data_show_existing_records. "$data_a[$i]". '"|"'. "$data_b[$i]". '"|"'. "$data_d[$i]". '"|"';
}

例を取得します。

$query_to_show =

WHERE (CompanyName = ? OR RegistrationNumber = ? OR VatCode = ?) OR (CompanyName = ? OR RegistrationNumber = ? OR VatCode = ?)

$data_show_existing_records =

first name"|"123"|"112233"|"second name"|"456"|"445566"|"

次に、配列に変換します

$data_show_existing_records = substr($data_show_existing_records, 0, -1);
$data_show_existing_records = explode('"|"', $data_show_existing_records);

そして、最後のクエリ

$query_show_existing_records = "
SELECT CompanyName, RegistrationNumber, VatCode 
FROM 18_6_TransactionPartners 
$query_to_show
";

そして準備/実行

$sql_show_existing_records = $db->prepare($query_show_existing_records);
$sql_show_existing_records->execute($data_show_existing_records);
$data_show_existing_records1 = $sql_show_existing_records->fetchAll(PDO::FETCH_ASSOC);

解決

クエリとデータの準備を次のように変更しました。

$flag = 0;//Set as WHERE
$data_show_existing_records = array();

foreach ($num_row_1 as $i => $row) {

if($flag == 0) {
$query_to_show = $query_to_show. 'WHERE (CompanyName = ? OR RegistrationNumber = ? OR VatCode = ?) ';
$flag = 1;
}
else {
$query_to_show = $query_to_show. 'OR (CompanyName = ? OR RegistrationNumber = ? OR VatCode = ?) ';
}

$data_show_existing_records[] = $data_a[$i];
$data_show_existing_records[] = $data_b[$i];
$data_show_existing_records[] = $data_d[$i];

}
4

1 に答える 1

1

SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens?バインドできるよりも多くの変数を指定したことを意味します。コードと説明を見ると、3 つの値を含むことができるカンマ区切りのリストを作成していますが、100 行が含まれている場合は 300 の値を含むこともできます。

質問に答えるには:データに含めることができない文字または一連の文字を区切り文字として選択します。データ内にある、またはデータ内で「可能性が低い」セパレータを選択すると、セキュリティ上の問題が発生する可能性があります。

特定の状況では、データをコンマ区切りの文字列に変換してから、再び配列に分解する理由はありません。最終的な形式に直接追加するだけです (複数のクエリを実行する場合は、ほとんどの場合 2 次元配列です)。

$output = Array();
for( $i = 0; $i < count( $data_a ); $i++ ) {
  $output[] = Array( $data_a[$i], $data_b[$i], $data_d[$i] );
}

/*** var_dump( $output );
   * Array(
   *   Array( 1, 2, 3 ),
   *   Array( 4, 5, 6 ),
   *   Array( 7, 8, 9 ), etc...
   * );
 ***/

foreach( $output as $k => $row ) {
  /*** Do your query
     * $row contains 3 values for this query; next loop it contains the next 3 values
   ***/
}
于 2013-08-10T09:19:22.817 に答える