1

MySQL で次の SQL クエリを使用しています。

"SELECT SUBSTRING(invoices.dateCreated, 1, 7) AS month, 
        account.name AS accountName, 
        account.id AS accountId, 
        invoices.invId AS invoiceId, 
        productType.title AS productTitle, 
        sum(invoiceItems.cost*invoiceItems.quantity) AS totalValue,
        sum(invoiceItems.quantity) AS totalQuantity
 FROM account LEFT JOIN invoices ON invoices.accountId = account.id
          LEFT JOIN invoiceItems ON invoices.id = invoiceItems.invoiceId
      LEFT JOIN productType ON invoiceItems.productTypeId = productType.id
 WHERE invoices.statusId != 'S62FD452B1D4'
 GROUP BY invoiceItems.productTypeId, invoices.invId   
 ORDER BY month DESC, accountName ASC, invoices.id ASC    
 LIMIT ".$start_limit.", ".$records_per_page.";"

これは、クエリを制限するセクションがなくても問題なく機能します。ただし、制限セクションを追加すると、変数$start_limit$records_per_pageは値がありませんが、変数の周りの行をジグすると、クエリになります。これは、変数を囲む引用符を に変更した場合にも当てはまります'.$start_limit.'。ただし、これではクエリが機能しないようです。

私が間違っていることについてのアドバイスや助けをいただければ幸いです。

2 つの変数の値は 100% 確実に渡されます。この例では、開始制限 = 0、終了制限 (ページあたり) = 50 です。確認したところ、50 は制限を大きく下回っています。

問題は、SQL エラーのポップアップが表示されると、次のように表示されることです。

SELECT SUBSTRING(invoices.dateCreated, 1, 7) AS month, 
       account.name AS accountName, 
       account.id AS accountId, 
       invoices.invId AS invoiceId, 
       productType.title AS productTitle, 
       sum(invoiceItems.cost*invoiceItems.quantity) AS totalValue,
       sum(invoiceItems.quantity) AS totalQuantity 
FROM account LEFT JOIN invoices ON invoices.accountId = account.id 
             LEFT JOIN invoiceItems ON invoices.id = invoiceItems.invoiceId 
             LEFT JOIN productType ON invoiceItems.productTypeId = productType.id 
WHERE invoices.statusId != 'S62FD452B1D4' 
GROUP BY invoiceItems.productTypeId, invoices.invId 
ORDER BY month DESC, accountName ASC, invoices.id ASC 
LIMIT , ;

そして、変数がそこにあるかどうかを確認するために物事を変更すると、次のようになります。

SELECT SUBSTRING(invoices.dateCreated, 1, 7) AS month, 
       account.name AS accountName, 
       account.id AS accountId, 
       invoices.invId AS invoiceId, 
       productType.title AS productTitle, 
       sum(invoiceItems.cost*invoiceItems.quantity) AS totalValue, 
       sum(invoiceItems.quantity) AS totalQuantity 
FROM account LEFT JOIN invoices ON invoices.accountId = account.id 
             LEFT JOIN invoiceItems ON invoices.id = invoiceItems.invoiceId 
             LEFT JOIN productType ON invoiceItems.productTypeId = productType.id 
WHERE invoices.statusId != 'S62FD452B1D4' 
GROUP BY invoiceItems.productTypeId, invoices.invId 
ORDER BY month DESC, accountName ASC, invoices.id ASC 
LIMIT '.0.', '.50.' ;

これらの値はどちらもユーザーが指定するものではありません。それはあまり問題ではありません。同じことをうまくやっている100の同様の1からのこの1つのクエリで、変数が異常に動作している理由がわかりません。これの唯一の違いは、グループ化と順序付けの数です。これは違いを生むでしょうか?

4

3 に答える 3

1

$start_limitおよび/または人口が少ない場合$records_per_pageは、問題が発生します。ただし、必要に応じて、クエリに配置する前にデフォルト値を標準値に設定した場合は、次のようになります。

// default them values to 0 and 50
$start_limit = empty($start_limit) ? 0 : $start_limit;
$records_per_page = empty($records_per_page) ? 50 : $records_per_page;
// may also want to check (empty(...) || $var < 0 || $var > $threshold) as well.

次に、あなたのビジネスに取り掛かります。

$sql = "SELECT " . /* ... */ " LIMIT " . $start_limit . "," . $records_per_page;

ただし、これらのいずれか(または両方)がユーザー提供である場合(またはユーザーがこれらの値を変更する機会がある場合)、クエリに配置する前にまずそれらをサニタイズすることに注意してください。例えば

$start_limit = (int) $_REQUEST['start_limit'];
if ($start_limit < 0) // can't be <0
  $start_limit = 0;

$records_per_page = (int) $_REQUEST['records_per_page'];
if ($records_per_page < 10) // can't be <10
  $records_per_page = 10;
else if ($records_per_page > 100) // can't be >100
  $records_per_page = 100;

次に、$start_limitのような脅迫的なものが含まれていないことを確認します;SELECT password FROM admin_table;。(SQLインジェクション

あなたの質問は少しあいまいですが、私が軌道に乗っていない場合は、質問を更新してください。私の答えでも同じことをします。

于 2012-09-04T14:28:12.177 に答える
0

$start_limitおよびの値$records_per_pageはおそらく無効であるか、範囲外です。おそらく、それらを確実にログに記録してみてください。

于 2012-09-04T14:27:45.523 に答える
0

これに PDO 拡張機能を使用できますか?

あなたのコードは SQL インジェクションを起こしやすいです。PDO または MySQLi 拡張機能を使用します。

PDO 拡張機能を使用した例:

<?php

    $query = "SELECT SUBSTRING(invoices.dateCreated, 1, 7) AS month, account.name AS accountName, account.id AS accountId, invoices.invId AS invoiceId, productType.title AS productTitle, sum(invoiceItems.cost*invoiceItems.quantity) AS totalValue, sum(invoiceItems.quantity) AS totalQuantity
             FROM account
             LEFT JOIN invoices ON invoices.accountId = account.id
             LEFT JOIN invoiceItems ON invoices.id = invoiceItems.invoiceId
             LEFT JOIN productType ON invoiceItems.productTypeId = productType.id
             WHERE invoices.statusId != 'S62FD452B1D4'
             GROUP BY invoiceItems.productTypeId, invoices.invId   
             ORDER BY month DESC, accountName ASC, invoices.id ASC    
             LIMIT ?, ?;"


    $stmt = $dbh->prepare($query);
    $stmt->bindParam(1, $start_limit, PDO::PARAM_INT);
    $stmt->bindParam(2, $records_per_page, PDO::PARAM_INT);

    $stmt->execute();
    // other codes here

?>
于 2012-09-04T14:33:28.773 に答える