参数准备语句的数量错误

Wrong number of parameter prepared statements

我正在使用准备好的语句来改进我正在执行的查询,但它生成了错误:

Wrong number of parameters

查询如下:

$start = new DateTime('first monday of January 2016');
$end   = new DateTime('last day of December 2016');

$sql = "SELECT ".$generalLand."
                         product AS product,
                         Week AS label,
                         ROUND(SUM(harvest)/SUM(production),2) AS value
                  FROM (
                          (
                              SELECT ".$fieldLand."
                                     pr_products.product,
                                     CONCAT(YEAR(:dates),'-', LPAD(WEEK(:dates1),2,'0')) AS Week,
                                     SUM(IF(sw_sowing.type = 'SW', sw_sowing.quantity,0)) AS PlantSowing,
                                     SUM(IF(ROUND(DATEDIFF(TIMESTAMPADD(DAY,(6-WEEKDAY(:dates2)),:dates3), sw_sowing.date)/7) >= pr_products.week_production AND sw_sowing.type = 'SW',sw_sowing.quantity,0)) AS production,
                                     0 AS Harvest
                              FROM (
                                      SELECT max(sw_sowing.id) AS id
                                      FROM sw_sowing
                                      WHERE sw_sowing.status != 0
                                      AND sw_sowing.date <= TIMESTAMPADD(DAY,(6-WEEKDAY(:dates4)),:dates5)
                                      GROUP BY sw_sowing.id_production_unit_detail
                                   ) AS sw
                              INNER JOIN sw_sowing ON sw_sowing.id = sw.id
                              INNER JOIN pr_products ON pr_products.id = sw_sowing.id_product
                              INNER JOIN pr_varieties ON sw_sowing.id_variety = pr_varieties.id
                              ".$innerSowing."
                              WHERE pr_varieties.code != 1
                              AND sw_sowing.id_product = 1
                              AND sw_sowing.status = 100
                              AND sw_sowing.id_tenant = :id_tenant
                              ".$consultSowing."
                              GROUP BY pr_products.product
                              HAVING plantSowing > 0
                              ORDER BY pr_products.product
                          )
                          UNION ALL
                          (
                              SELECT  ".$fieldLand."
                                      pr_products.product,
                                      CONCAT(YEAR(:dates6),'-', LPAD(WEEK(:dates7),2,'0')) AS Week,
                                      0 AS plantSowing,
                                      0 AS Production,
                                      SUM(pf_harvest.quantity) AS Harvest
                              FROM pf_harvest
                              INNER JOIN pr_products ON pr_products.id = pf_harvest.id_product
                              INNER JOIN pr_varieties ON pr_varieties.id = pf_harvest.id_variety
                              INNER JOIN pf_performance ON pf_performance.id = pf_harvest.id_performance
                              ".$innerHarvest."
                              WHERE pf_harvest.date BETWEEN TIMESTAMPADD(DAY,(0-WEEKDAY(:dates8)),:dates9)
                              AND TIMESTAMPADD(DAY,(6-WEEKDAY(:dates10)),:dates11)
                              AND pr_varieties.code != 1
                              AND pf_harvest.id_product = 1
                              AND pf_performance.status = 100
                              ".$consultHarvest."
                              AND pf_harvest.id_tenant = :id_tenant1
                              GROUP BY pr_products.product
                              ORDER BY pr_products.product
                              )
                          ) AS sc
                  GROUP BY product, label
                  ORDER BY label";

        $statement = $this->db->prepare($sql);
        $id_tenant = $this->getIdTenant();
        foreach($datePeriod AS $dates){

          $values = [
            ':dates'      => $dates->format('Y-m-d'),
            ':dates1'     => $dates->format('Y-m-d'),
            ':dates2'     => $dates->format('Y-m-d'),
            ':dates3'     => $dates->format('Y-m-d'),
            ':dates4'     => $dates->format('Y-m-d'),
            ':dates5'     => $dates->format('Y-m-d'),
            ':dates6'     => $dates->format('Y-m-d'),
            ':dates7'     => $dates->format('Y-m-d'),
            ':dates8'     => $dates->format('Y-m-d'),
            ':dates9'     => $dates->format('Y-m-d'),
            ':dates10'    => $dates->format('Y-m-d'),
            ':dates11'    => $dates->format('Y-m-d'),
            ':id_tenant'  => $id_tenant,
            ':id_tenant1' => $id_tenant

          ];

          $result = $this->db->executePrepared($statement , $values);

        }

我知道这是因为我在查询中的绑定数量。

每个:date都是相同的日期,但是我放了不同的值,因为变量不能重复。

我也在尝试改进我的查询,因为我使用了一个循环来显示一年中每个星期一的日期以及我在查询中输入的那些日期。

为此我这样咨询

如果有人能给我建议,我将不胜感激。

此致!

在你的 foreach 循环中:

foreach($datePeriod AS $dates){

          $values = [
            ':dates'      => $dates->format('Y-m-d'),
            ':dates1'     => $dates->format('Y-m-d'),
            ':dates2'     => $dates->format('Y-m-d'),
            ':dates3'     => $dates->format('Y-m-d'),
            ':dates4'     => $dates->format('Y-m-d'),
            ':dates5'     => $dates->format('Y-m-d'),
            ':dates6'     => $dates->format('Y-m-d'),
            ':dates7'     => $dates->format('Y-m-d'),
            ':dates8'     => $dates->format('Y-m-d'),
            ':dates9'     => $dates->format('Y-m-d'),
            ':dates10'    => $dates->format('Y-m-d'),
            ':dates11'    => $dates->format('Y-m-d'),
            ':id_tenant'  => $id_tenant,
            ':id_tenant1' => $id_tenant

          ];

          $result = $this->db->executePrepared($statement , $values);

}

$dates 被格式化 11 次。您知道每次都是同一日期吗?这可能是问题所在吗?

也许你的意思是这样的?

foreach ($datePeriod as $dates) {
  $dateHolder[] = $dates->format('Y-m-d')
}

$i = 0;

$values = [
  ':dates'      => $dateHolder[$i++],
  ':dates1'     => $dateHolder[$i++],
  ':dates2'     => $dateHolder[$i++],
  ':dates3'     => $dateHolder[$i++],
  ':dates4'     => $dateHolder[$i++],
  ':dates5'     => $dateHolder[$i++],
  ':dates6'     => $dateHolder[$i++],
  ':dates7'     => $dateHolder[$i++],
  ':dates8'     => $dateHolder[$i++],
  ':dates9'     => $dateHolder[$i++],
  ':dates10'    => $dateHolder[$i++],
  ':dates11'    => $dateHolder[$i++],
  ':id_tenant'  => $id_tenant,
  ':id_tenant1' => $id_tenant
];

$result = $this->db->executePrepared($statement , $values);

我知道是什么问题了:

当我使用executePrepared时我需要使用三个参数,所以在我的例子中我需要使用这个:

$start = new DateTime('first monday of January 2016');
$end   = new DateTime('last day of December 2016');

$sql = "SELECT ".$generalLand."
                         product AS product,
                         Week AS label,
                         ROUND(SUM(harvest)/SUM(production),2) AS value
                  FROM (
                          (
                              SELECT ".$fieldLand."
                                     pr_products.product,
                                     CONCAT(YEAR(:dates),'-', LPAD(WEEK(:dates1),2,'0')) AS Week,
                                     SUM(IF(sw_sowing.type = 'SW', sw_sowing.quantity,0)) AS PlantSowing,
                                     SUM(IF(ROUND(DATEDIFF(TIMESTAMPADD(DAY,(6-WEEKDAY(:dates2)),:dates3), sw_sowing.date)/7) >= pr_products.week_production AND sw_sowing.type = 'SW',sw_sowing.quantity,0)) AS production,
                                     0 AS Harvest
                              FROM (
                                      SELECT max(sw_sowing.id) AS id
                                      FROM sw_sowing
                                      WHERE sw_sowing.status != 0
                                      AND sw_sowing.date <= TIMESTAMPADD(DAY,(6-WEEKDAY(:dates4)),:dates5)
                                      GROUP BY sw_sowing.id_production_unit_detail
                                   ) AS sw
                              INNER JOIN sw_sowing ON sw_sowing.id = sw.id
                              INNER JOIN pr_products ON pr_products.id = sw_sowing.id_product
                              INNER JOIN pr_varieties ON sw_sowing.id_variety = pr_varieties.id
                              ".$innerSowing."
                              WHERE pr_varieties.code != 1
                              AND sw_sowing.id_product = 1
                              AND sw_sowing.status = 100
                              AND sw_sowing.id_tenant = :id_tenant
                              ".$consultSowing."
                              GROUP BY pr_products.product
                              HAVING plantSowing > 0
                              ORDER BY pr_products.product
                          )
                          UNION ALL
                          (
                              SELECT  ".$fieldLand."
                                      pr_products.product,
                                      CONCAT(YEAR(:dates6),'-', LPAD(WEEK(:dates7),2,'0')) AS Week,
                                      0 AS plantSowing,
                                      0 AS Production,
                                      SUM(pf_harvest.quantity) AS Harvest
                              FROM pf_harvest
                              INNER JOIN pr_products ON pr_products.id = pf_harvest.id_product
                              INNER JOIN pr_varieties ON pr_varieties.id = pf_harvest.id_variety
                              INNER JOIN pf_performance ON pf_performance.id = pf_harvest.id_performance
                              ".$innerHarvest."
                              WHERE pf_harvest.date BETWEEN TIMESTAMPADD(DAY,(0-WEEKDAY(:dates8)),:dates9)
                              AND TIMESTAMPADD(DAY,(6-WEEKDAY(:dates10)),:dates11)
                              AND pr_varieties.code != 1
                              AND pf_harvest.id_product = 1
                              AND pf_performance.status = 100
                              ".$consultHarvest."
                              AND pf_harvest.id_tenant = :id_tenant1
                              GROUP BY pr_products.product
                              ORDER BY pr_products.product
                              )
                          ) AS sc
                  GROUP BY product, label
                  ORDER BY label";

        $statement = $this->db->prepare($sql);
        $id_tenant = $this->getIdTenant();
        foreach($datePeriod AS $dates){

          $values = [
            ':dates'      => $dates->format('Y-m-d'),
            ':dates1'     => $dates->format('Y-m-d'),
            ':dates2'     => $dates->format('Y-m-d'),
            ':dates3'     => $dates->format('Y-m-d'),
            ':dates4'     => $dates->format('Y-m-d'),
            ':dates5'     => $dates->format('Y-m-d'),
            ':dates6'     => $dates->format('Y-m-d'),
            ':dates7'     => $dates->format('Y-m-d'),
            ':dates8'     => $dates->format('Y-m-d'),
            ':dates9'     => $dates->format('Y-m-d'),
            ':dates10'    => $dates->format('Y-m-d'),
            ':dates11'    => $dates->format('Y-m-d'),
            ':id_tenant'  => $id_tenant,
            ':id_tenant1' => $id_tenant

          ];

          $types = [
            ':dates'      => Column::BIND_PARAM_STR,
            ':dates1'     => Column::BIND_PARAM_STR,
            ':dates2'     => Column::BIND_PARAM_STR,
            ':dates3'     => Column::BIND_PARAM_STR,
            ':dates4'     => Column::BIND_PARAM_STR,
            ':dates5'     => Column::BIND_PARAM_STR,
            ':dates6'     => Column::BIND_PARAM_STR,
            ':dates7'     => Column::BIND_PARAM_STR,
            ':dates8'     => Column::BIND_PARAM_STR,
            ':dates9'     => Column::BIND_PARAM_STR,
            ':dates10'    => Column::BIND_PARAM_STR,
            ':dates11'    => Column::BIND_PARAM_STR,
            ':id_tenant'  => Column::BIND_PARAM_INT,
            ':id_tenant1' => Column::BIND_PARAM_INT

          ];

          $result = $this->db->executePrepared($statement , $values, $types);

        }

我添加了 $types[],因此它不起作用!

希望对其他人有所帮助!