2017-02-08 34 views
1

我使用準備好的發言改善,我做一個查詢語句,但它產生的錯誤:數參數的錯誤準備

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是相同的日期,但我把一個不同的值,因爲變量不能重複。

我也試圖改進我的查詢,因爲我用一個循環顯示了我每年的每個星期一的日期以及我放入查詢的日期。

爲此,我以這種方式

諮詢如果誰能給我一個建議,我將不勝感激。

問候!

+1

建議閱讀:[如何創建一個最小,完整和可驗證的示例](http://stackoverflow.com/help/mcve) – wogsland

+0

是的,我可以給你一個建議 - 不要指望任何人都可以幫助你解決這個問題。 – Hogan

+0

對不起,我要更新我的問題 –

回答

0

在您的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); 

} 

$日期是越來越格式化的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); 
+0

我需要每個變量中的相同日期,因此我做了這個,但我要審查! –

+0

如果您需要每個變量中的相同日期,那麼只需創建一個「日期」變量並使用一個而不是11個單獨的變量。 –

+0

是的,但我使用phalcon,它只允許查詢中的一個變量 –

0

我知道是什麼問題:

當我使用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); 

     } 

我就將此$類型[],因此它沒有工作!

我希望它可以幫助別人!