【问题标题】:Error: INSERT INTO / VALUES ('Array'); Column count doesn't match value count at row 1错误:插入/值('数组');列计数与第 1 行的值计数不匹配
【发布时间】:2017-02-20 18:58:06
【问题描述】:

我整个星期天都在试图弄清楚这一点,但我不知道如何正确表达。它通过 Cron 作业每小时检查一次是否有新的销售。然后取产品编号和收据编号。它使用产品编号检查信息数据库,并从每一行中收集新销售产品的所有信息。然后对于每个售出的产品,我需要在数组末尾添加收据编号,并将所有这些信息插入到保存所有销售额的第三个数据库中。

我的主要问题是我合并它们,它不会插入到数据库中。我第一次让它工作,但只抓住了第一行。

<?php
//find out current time and 1 hour ago
$current_time = strtotime("now");
$tenmin_ago = strtotime('-10 min');
$hour_ago = strtotime('-1 hour');

//////////////////////////////////////////////////////////////////
/////////////////// Connect to Sales Database  ///////////////////
//////////////////////////////////////////////////////////////////

// connect to EMAP sales MySQL server
$server='localhost';
$user='user';
$password='pass';
$database='sales_data';

$con = mysqli_connect($server,$user,$password,$database);

// Check connection
if (mysqli_connect_errno())
  {
  echo "Failed to connect to MySQL: SALES " . mysqli_connect_error();
  }

//////////////////////////////////////////////////////////////////
///////////////////// Connect to EM Database  ////////////////////
//////////////////////////////////////////////////////////////////

//EM connect to DLGuard-EM MySQL server
$em_server='localhost';
$em_user='user';
$em_password='pass';
$em_database='databaseEM';

$em_con = mysqli_connect($em_server,$em_user,$em_password,$em_database);

//EM Check connection
if (mysqli_connect_errno())
  {
  echo "Failed to connect to MySQL: EM " . mysqli_connect_error();
  }

//EM grab store name
$em_dlg_store = "EM";

$em_rows = array();   
$em_request = "SELECT * FROM customers WHERE date BETWEEN $hour_ago AND {$current_time}";
$em_result = mysqli_query($em_con, $em_request) or die("ERROR NO SALES EM");
 while ($em_row = mysqli_fetch_array($em_result)) {
    $em_prod_num = $em_row["prod_num"];
    $em_rows[] = $em_row["receipt"];
    }

//////////////////////////////////////////////////////////////////
///////////////////// Grab info for EM Sales  ////////////////////
//////////////////////////////////////////////////////////////////

$emap_rows = array();
$emap_request = "SELECT * FROM all_products WHERE dlgprod_num='{$em_prod_num}' AND dlg_store='{$em_dlg_store}'";
$emap_result = mysqli_query($con, $emap_request) or die("ERROR dlg prod num EM");
 while ($emap_row = mysqli_fetch_array($emap_result)) $emap_rows[] = $emap_row;

$em_emap_rows = array_merge($em_rows, $emap_rows);
 /*VALUES ('$emap_sku', '$emap_dlgprod_num', '$emap_book_title', '$emap_dlgprod_price', '$emap_author_name', '$emap_author_email', '$emap_publisher', '$emap_dlg_store', '$em_receipt');";*/
// 1
$em_add_sql  = "INSERT INTO all_author_sales (sku, dlgprod_num, dlgprod_nam, dlgprod_price, author_name, author_email, publisher, dlg_store, dlgcustomer_receipt)
VALUES ('$em_emap_rows');";         
if ($con->multi_query($em_add_sql) === TRUE) {
} else {
    echo "Error: " . $em_add_sql . "<br>" . $con->error;
}

?>

xxxxxxxxxxxxxxxxxxxxxxxxxxx 更新 2/27/17 xxxxxxxxxxxxxxxxxxxxxx

这是一个更新的版本,它获取了信息,但它丢失了在合并或字符串部分某处接收的数组。此外,它使顺序错误。而不是 UPC,产品编号,标题,价格等然后开始第二次销售的下一行,当有两次销售时,它将它们混合在一起,如 upc,UPC,产品编号,产品编号,标题,标题,价格,价格。 这是新的错误。我非常接近解决这个问题,谢谢。我将制作 4 个脚本,让他们每小时交替检查所有 4 家商店的销售情况。

Warning: array_map(): Argument #2 should be an array in  /home1/lotscav1/public_html/Sales/scripts/sales-notif.php on line 53
Warning: implode(): Invalid arguments passed in  /home1/lotscav1/public_html/Sales/scripts/sales-notif.php on line 53
Error: INSERT INTO all_author_sales (sku, dlgprod_num, dlgprod_nam,  dlgprod_price, author_name, author_email, publisher, dlg_store,  dlgcustomer_receipt) VALUES ('('EM2200002','EM2200002','1','1','Island  Girl','Island Girl','4.95','4.95','Marshall Gibson','Marshall  Gibson','jasminerice1993@gmail.com','jasminerice1993@gmail.com','Dan  Cuneo','Dan Cuneo','EM','EM'),(),');
You have an error in your SQL syntax; check the manual that    corresponds to your MySQL server version for the right syntax to use near   'EM2200002','EM2200002','1','1','Island Girl','Island   Girl','4.95','4.95','Marsha' at line 2
Array

这是更新的代码

    <?php
//find out current time and 1 hour ago
$current_time = strtotime("now");
$hour_ago = strtotime('-24 hour');

//////////////////////////////////////////////////////////////////
/////////////////// Connect to Sales Database  ///////////////////
//////////////////////////////////////////////////////////////////

// connect to EMAP sales MySQL server
$mysqli = new mysqli("localhost", "username", "password",     "database");
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") "  . $mysqli->connect_error;
}

//////////////////////////////////////////////////////////////////
///////////////////// Connect to EM Database  ////////////////////
//////////////////////////////////////////////////////////////////
$mysqli_em = new mysqli("localhost", "username", "password",    "database");
if ($mysqli_em->connect_errno) {
echo "Failed to connect to MySQL_EM: (" . $mysqli_em->connect_errno .     ") " . $mysqli_em->connect_error;
}

//EM grab store name
$em_dlg_store = "EM";


$em_rows = array();   
$em_request = "SELECT * FROM customers WHERE date BETWEEN '$hour_ago'    AND '$current_time'";
$em_result = mysqli_query($mysqli_em, $em_request) or die("Error No      Sales EM");
while ($em_row = mysqli_fetch_array($em_result)) {
$em_prod_num = $em_row["prod_num"];
$em_rows[] = $em_row["receipt"];
}
//////////////////////////////////////////////////////////////////
///////////////////// Grab info for EM Sales  ////////////////////
//////////////////////////////////////////////////////////////////
$emap_rows = array();
$emap_request = "SELECT * FROM all_products WHERE       dlgprod_num='$em_prod_num' AND dlg_store='$em_dlg_store'";
$emap_result = mysqli_query($mysqli, $emap_request) or die("Error dlg  prod num EM");
while ($emap_row = mysqli_fetch_array($emap_result)) $emap_rows[] =     $emap_row;

$em_emap_rows = array_merge($emap_rows, $em_rows);
/*VALUES ('$emap_sku', '$emap_dlgprod_num', '$emap_book_title',    '$emap_dlgprod_price', '$emap_author_name', '$emap_author_email',     '$emap_publisher', '$emap_dlg_store', '$em_receipt');";*/
// 1
$string = "";
foreach ($em_emap_rows as $key => $innerArr) {
$result = implode( array_map('quoteItems', $innerArr), ",");
$string .= "(" . $result . ")";

if( $key != count($array) - 1 ){
    $string .= ",";
}
}
function quoteItems($item){
return "'" . $item . "'";
}
//$em_rowss = implode(",", $em_rows); this turns the receipt array     into a string
$em_add_sql  = "INSERT INTO all_author_sales (sku, dlgprod_num,      dlgprod_nam, dlgprod_price, author_name, author_email, publisher,       dlg_store, dlgcustomer_receipt)
VALUES ('$string');";           
if ($mysqli->multi_query($em_add_sql) === TRUE) {
} else {
echo "Error: " . $em_add_sql . "<br>" . $mysqli->error . "<br>" .           $em_rows;
}

?>

【问题讨论】:

标签: php mysql mysql-insert-id


【解决方案1】:

我假设代码的顶部部分有效。但是从这里有几件事需要检查:

//////////////////////////////////////////////////////////////////
///////////////////// Grab info for EM Sales  ////////////////////
//////////////////////////////////////////////////////////////////

$emap_rows = array();
$emap_request = "SELECT * FROM all_products WHERE dlgprod_num='{$em_prod_num}' AND dlg_store='{$em_dlg_store}'";
$emap_result = mysqli_query($con, $emap_request) or die("ERROR dlg prod num EM");

 while ($emap_row = mysqli_fetch_array($emap_result)) $emap_rows[] = $emap_row;

基本上你把从查询中得到的所有行放到$emap_rows数组中,所以它看起来更像:

$emap_rows = array(
    0 => array(
        'sku' => 'value',
        'dlgprod_num' => 'value',
        'dlgprod_nam' => 'value',
        ...
    ),
    1 => array(
        'sku' => 'value2',
        'dlgprod_num' => 'value2',
        'dlgprod_nam' => 'value2',
        ...
    ),
)

您是否只期望上一个查询的 1 个结果? 我假设您只希望收到 1 行,否则对我来说毫无意义。我假设您想将$em_rows 值(收据)添加到每个$emap_rows

// $em_emap_rows = array_merge($em_rows, $emap_rows);

也许你可以试试:

foreach( $emap_rows as $emap_row ) {
    $v = array_values( $emap_row ); 
    $v[] = $em_rows[0]; // because I expect only 1 result, added to array

    $em_add_sql  = "INSERT INTO all_author_sales ";
    $em_add_sql .= " (sku, dlgprod_num, dlgprod_nam, dlgprod_price, author_name, author_email, publisher, dlg_store, dlgcustomer_receipt) ";
    $em_add_sql .= " VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ? )"; 

    $em_con->prepare( $em_add_sql );
    $em_con->bind_param( 'sssssssss', $v[0], $v[1], $v[2], $v[3], $v[4], $v[5], $v[6], $v[7], $v[8] );
    $em_con->execute();
}

总而言之,我建议从头开始创建整个脚本,使其不易受到注入等的影响,并且在使用哪些数据方面更加精确。如果您没有在查询中指定(例如使用 LIMIT),请不要依赖只获得 1 个结果。 不要依赖数据顺序,而是依赖它的键。我在上面的例子中使用过 $v[0] 但最好使用$emap_row['sku']

注意:代码未经测试,只是我尝试理解脚本并提供一些帮助。

【讨论】:

    【解决方案2】:

    看起来这一切都可以在一个查询中完成:

    INSERT INTO all_author_sales (sku, dlgprod_num, dlgprod_nam, 
           dlgprod_price, author_name, author_email, publisher, dlg_store, dlgcustomer_receipt)
    
        SELECT ap.sku, ap.dlgprod_num, ap.dlgprod_nam, ap.dlgprod_price, 
               ap.author_name, ap.author_email, ap.publisher, ap.dlg_store, c.receipt 
            FROM customers c
            INNER JOIN all_products ap 
                    ON  c.prod_num = ap.dlgprod_num
                    AND c.date BETWEEN '{$hour_ago}' AND '{$current_time}'
                    AND dlg_store='{$em_dlg_store}'
    

    注意几点:

    • 从有问题的查询中可以看出,receiptcustomers 表中的一列,它以dlgcustomer_receipt 进入all_author_sales。但是,对于上述查询的SELECT 部分中的所有ap.* 列,如果它们与查询中写入的不同,请使用all_products 表中的适当列名。

    • 由于您使用的是 MySQLi,为了简单和安全,请考虑更改您的代码以包含 Prepared Queries

    【讨论】:

      【解决方案3】:

      您只需将数组作为字符串VALUES('$em_emap_rows') 插入。那是错误。

      解决方案

      循环数组并引用每个数组中的每个元素,然后在主数组中内爆数组。

      $string = "";
      foreach ($em_emap_rows as $key => $innerArr) {
          $result = implode( array_map('quoteItems', $innerArr), ",");
          $string .= "(" . $result . ")";
      
          if( $key != count($array) - 1 ){
              $string .= ",";
          }
      }
      function quoteItems($item){
          return "'" . $item . "'";
      }
      

      那么使用Values($string)

      【讨论】:

        【解决方案4】:

        感谢您的所有帮助。由于我的独特情况,我无法按照你给我的方式工作。然而,在一位老朋友的帮助下,它激发了我对工作解决方案的兴趣。这是现在可以运行的代码。

            <?php
        //find out current time and 1 hour ago
        date_default_timezone_set('America/New_York');
        $current_time = strtotime("now");
        $hour_ago = strtotime('-1 hour');
        
        //////////////////////////////////////////////////////////////////
        /////////////////// Connect to Sales Database  ///////////////////
        //////////////////////////////////////////////////////////////////
        
        $mysqli_s = new mysqli("localhost", "user", "password", 
        "server_sales_data");
        if ($mysqli_s->connect_errno) {
        echo "Failed to connect to MySQL: (" . $mysqli_s->connect_errno . ") 
        " . $mysqli_s->connect_error;
        }
        
        //////////////////////////////////////////////////////////////////
        ///////////////////// Connect to EM Database  ////////////////////
        //////////////////////////////////////////////////////////////////
        
        $mysqli_em = new mysqli("localhost", "user", "password", 
        "server_dlgEM");
        if ($mysqli_em->connect_errno) {
        echo "Failed to connect to MySQL_EM: (" . $mysqli_em->connect_errno . 
        ") " . $mysqli_em->connect_error;
        }
        
        //Grab store name
        $dlg_store = "EM";
        
        $em_request = "SELECT * FROM customers WHERE date BETWEEN '$hour_ago' 
        AND '$current_time'";
        $em_result = mysqli_query($mysqli_em, $em_request) or die("Error No 
        Sales EM");
        while ($em_row = mysqli_fetch_array($em_result)) {
        $em_prod_num = $em_row["prod_num"];
        $em_receipt = $em_row["receipt"];
        
        
        //////////////////////////////////////////////////////////////////
        ///////////////////// Grab info for EM Sales  ////////////////////
        //////////////////////////////////////////////////////////////////
        
        $request_s = "SELECT * FROM all_products WHERE 
        dlgprod_num='$em_prod_num' AND dlg_store='$dlg_store'";
        $result_s = mysqli_query($mysqli_s, $request_s) or die("Error dlg 
        prod num EM");
        while ($row_s = mysqli_fetch_array($result_s)) {
                $sku_s = $row_s["sku"];
                $dlgprod_num_s = $row_s["dlgprod_num"];
                $book_title_s = addslashes($row_s["book_title"]);
                $dlgprod_price_s = $row_s["dlgprod_price"];
                $author_name_s = addslashes($row_s["author_name"]);
                $author_email_s = $row_s["author_email"];
                $publisher_s = $row_s["publisher"];
                $dlg_store_s = $row_s["dlg_store"];
        
                    $add_sql_s  = "INSERT INTO all_author_sales SET
                    `sku`='$sku_s', 
                    `dlgprod_num`='$dlgprod_num_s',
                    `dlgprod_nam`='$book_title_s',
                    `dlgprod_price`='$dlgprod_price_s',
                    `author_name`='$author_name_s',
                    `author_email`='$author_email_s',
                    `publisher`='$publisher_s',
                    `dlg_store`='$dlg_store_s',
                    `dlgcustomer_receipt`='$em_receipt' ";  
        
        //create signature
        $sig = "The Admin Team at www.website.com";
        //to
        $admin_email = "admin@website.com";
        $to = array($author_email_s, $admin_email);
        
        //setup email headers
        $headers='From: ' . $admin_email . "\r\n" .
        'Reply-To: ' . $admin_email . "\r\n" .
        'X-Mailer: PHP/' . phpversion();
        $headers .= "MIME-Version: 1.0\r\n";
        $headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";
        $headers .= $emailbody."\n\n";
        
        //email subject and body
        $subject = "Your book stats";
        $message = "
        Hi $author_name_s,<br />
        I just wanted to send you a message and let you know that the book or 
        books below have just been purchased.<br /><br />
        
        Store: $dlg_store_s<br />
        Receipt: $em_receipt<br />
        Sku Number: $sku_s<br /><br />
        
        Book Title: $book_title_s<br />
        Publisher: $publisher_s<br />
        Product Number: $dlgprod_num_s<br />
        Price: $dlgprod_price_s<br /><br />
        
        Sincerely,<br />
        $sig<br /><br />
        
        To remove yourself from this notification, please send an email to 
        $admin_email with Unsubscribe in the subject line.
        ";
        
                    if ($mysqli_s->multi_query($add_sql_s) === TRUE) {
                    mail (implode(',', $to), $subject, $message, $headers); 
                    } else {
                        echo "Error: " . $add_sql_s . "<br>" . $mysqli_s-
        >error . "<br>" . $string;
                    }
        
        
            }
        
        
        
        }
        
        
        ?>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-07-03
          • 2023-04-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多