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.'. 但是,查询似乎不适用于此。

任何关于我做错了什么的建议或帮助将不胜感激。

这两个变量的值是 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.' ;

这些值都不是用户提供的。所以这不是太大的问题。我不确定为什么变量在这个来自数百个类似 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 回答