2017-07-30 213 views
1

我想查询大量数据到服务器,这里是我的代码:MySQL查询执行失败

$queryString = ""; 

$connect = mysqli_connect("localhost", "username", "password", "database"); 

$loopLength = 20; 
$currentGroup = 1; 
$currentLoopAmount = 0; 
$queryAmount = 5; 

for($v = 0; $v < ceil($loopLength/$queryAmount); $v++){ 
    //echo "Looping Main: " . $v . "<br>"; 
    //echo $loopLength - (($currentGroup - 1) * 10) . "<br>"; 
    if($loopLength - (($currentGroup - 1) * $queryAmount) >= $queryAmount){ 
     $currentLoopAmount = $queryAmount; 
    } 
    else{ 
     $currentLoopAmount = $loopLength - (($currentGroup - 1) * $queryAmount); 
    } 

    //echo $currentLoopAmount; 

    $queryString = ""; 

    for($q = (($currentGroup - 1) * $queryAmount); $q < $currentLoopAmount + (($currentGroup - 1) * $queryAmount); $q++){ 
     //echo "&nbsp;&nbsp;Looping Sub: " . $q . "<br>"; 
     $tempVariable = grabPageData($URLs[$q], $q); 

     $queryString .= $tempVariable; 
     if($q < $loopLength-1){ 
      $queryString .= ","; 
     } 
     else{ 
      $queryString .= ";"; 
     } 
    } 

    echo $queryString; 

    $query = "INSERT INTO PublicNoticesTable (url, county, paperco, date, notice, id) VALUES " . $queryString; 
    $result = mysqli_query($connect, $query); 

    if($result){ 
     echo "Success"; 
    } 
    else{ 
     echo "Failed : " . mysqli_error($connect) . "<br>"; 
    } 

    $currentGroup += 1; 
} 

$loopLength变量是动态的,可以在数千或潜在十万。我设计了这个功能,将这个庞大的数字划分为一批较小的查询,因为我无法一次性通过GoDaddy在我的共享托管服务上传所有数据。变量$queryAmount代表较小的查询有多大。

下面是插入到表中的其中一个值集的示例: 这是公告中的数据,表示我的代码在grabPageData()函数中检索到。

('http://www.publicnoticeads.com/az/search/view.asp?T=PN&id=37/7292017_24266919.htm','Pima','Green Valley News and Sun','2017/07/30',' ___________________________ARIZONA SUPERIOR COURT, PIMA COUNTYIn the Matter of the Estate of:JOSEPH T, DILLARD, SR.,Deceased.DOB: 10/09/1931No. PB20170865NOTICE TO CREDITORS(FOR PUBLICATION)NOTICE IS HEREBY GIVEN that DANA ANN DILLARD CALL has been appointed Personal Representative of this Estate. All persons having claims against the Estate are required to present their claimswithin four months after the date of the firat publication of this notice or the claims will be forever barred. Claims must be presented by delivering or mailing a written statement of the claim to the Personal Representative at the Law Offices of Michael W. Murray, 257 North Stone Avenue, Tucson, Arizona 85701.DATED this 17th day of July, 2017./S/ Micahel W. MurrayAttorney for the Personal RepresentativePub: Green Valley News & SunDate: July 23, 30, August 6, 2017 Public Notice ID: 24266919',' 24266919'), 

为了获得这些数据,我通过抓取页面并抓取它的函数来运行它。然后我通过这个功能把网页html代码:

function cleanData($data){ 
    $data = strip_tags($data); 
    //$data = preg_replace("/[^a-zA-Z0-9]/", "", $data); 
    //$data = mysql_real_escape_string($data); 
    return $data; 
} 

这给了我没有标签的内容,如你所见。这是问题。

该函数执行,一切似乎只是丹迪。然后(我不保持在10题的缘故取决于$queryAmount变量)的输出,你可以看到它会在功能类似的功能...

Failed : 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 '' at line 1 

怪异的是,当我有大量的数据,比如说$loopLength变量就像116.结果会输出,“失败:(错误)失败:(错误)辉...(错误)成功所以它只是实际查询最后一组数据???不确定

我不知道如何解决这个问题,我想要一个新鲜的眼睛,有人可以帮助我,我一直在努力解决这个问题...几个小时,试图找到解决方案

对不起,让这个问题的一个痛苦的对接:(

编辑:

我改变了代码从以前用mysql准备语句并没有什么...见下文:

$grabDataResults = [ 
     "url" => "", 
     "county" => "", 
     "paperco" => "", 
     "date" => "", 
     "notice" => "", 
     "id" => "", 
    ]; 

$connect = mysqli_connect("localhost", "bwt_admin", "Thebeast1398", "NewCoDatabase"); 

if($stmt = mysqli_prepare($connect, "INSERT INTO PublicNoticesTable (url, county, paperco, date, notice, id) VALUES (?, ?, ?, ?, ?, ?)")){ 

mysqli_stmt_bind_param($stmt, 'ssssss', $grabDataResults["url"], $grabDataResults["county"], $grabDataResults["paperco"], $grabDataResults["date"], $grabDataResults["notice"], $grabDataResults["id"]); 

$loopLength = 1; 

for($v = 0; $v < $loopLength; $v++){ 
    $grabDataResults = grabPageData($URLs[$v], $v); 
    mysqli_stmt_execute($stmt); 
    printf("%d Row inserted.\n", mysqli_stmt_affected_rows($stmt)); 
    printf("Error:\n", mysqli_stmt_error($stmt)); 
    echo "(" . $grabDataResults["url"] . "," . $grabDataResults["county"] . "," . $grabDataResults["paperco"] . "," . $grabDataResults["date"] . "," . $grabDataResults["notice"] . "," . $grabDataResults["id"] . ")"; 
} 

mysqli_stmt_close($stmt); 

mysqli_close($connect); 
} 

不幸的是,这是我从输出获得:

1 Row inserted. 0 Error: 

没有错误实际打印出来,该行是在serted。但是,当我导航到我的数据库,并查看已存储的值..他们都是空的。 echo语句输出这样的:

(http://www.publicnoticeads.com/az/search/view.asp?T=PN&id=31/7292017_24266963.htm,Yuma,Sun (Yuma), The,2017/07/30,, 24266963) 

所以我知道所有变量包含除$notice变量,它得到由我cleanData()功能出于某种原因被破坏的东西。

+1

FRO对目前为止的问题的评论 - 我肯定会使用准备好的语句并绑定这些值。如果您的数据来自网页,那么如果直接插入数据会导致您的SQL发生中断的可能性非常高,https://stackoverflow.com/questions/9629328/how-to-use-mysqli-prepared-statements-in -php可能会有帮助。 –

+0

我做了一些关于创建预处理语句的研究,并为了不直接插入而对值进行了绑定......看起来像是我的代码试图动态生成查询语句和东西将是一个巨大的混乱。我想我可以尝试一下,但就像我说过的,我可能会产生成千上万的数据行,不知道绑定语句会是什么样子,更不用说查询本身了。 – Pixelknight1398

+0

您可以使用1行插入来准备语句,然后每行数据只需执行准备好的语句和一行数据。 –

回答

0

你需要提取后的数据绑定,防止它和之前执行它...

$loopLength = 1; 

for($v = 0; $v < $loopLength; $v++){ 
    $grabDataResults = grabPageData($URLs[$v], $v); 

    mysqli_stmt_bind_param($stmt, 'ssssss', $grabDataResults["url"], 
      $grabDataResults["county"], $grabDataResults["paperco"], 
      $grabDataResults["date"], $grabDataResults["notice"], 
      $grabDataResults["id"]); 

    mysqli_stmt_execute($stmt); 
    printf("%d Row inserted.\n", mysqli_stmt_affected_rows($stmt)); 
    printf("Error:\n", mysqli_stmt_error($stmt)); 
    echo "(" . $grabDataResults["url"] . "," . $grabDataResults["county"] . "," . $grabDataResults["paperco"] . "," . $grabDataResults["date"] . "," . $grabDataResults["notice"] . "," . $grabDataResults["id"] . ")"; 
} 
+0

谢谢你,你的建议解决了我的问题! :)感谢帮助我,花了一分钟才开始。 – Pixelknight1398

0

我在查询中看到的主要错误是查询本身。您正在使用带有分隔字段和值的INSERT INTO。但是你忘记在价值观上使用pharentesis。

记住,使用INSERT INTO的如下:

First option: 
INSERT INTO table field1 = value1, field2 = value2; 

Second option: 
INSERT INTO table (field1, field2) VALUES (value1, value2); 

还有,记得逃脱各个领域和价值避免更多的错误:例:

First option: 
INSERT INTO `table` `field1` = 'value1', `field2` = 'value2'; 

Second option: 
INSERT INTO `table` (`field1`, `field2`) VALUES ('value1', 'value2'); 

如果您在使用mysqli驱动程序,为了更安全,您可以使用准备好的语句,让您的值自动转义。在这种情况下,查询的语法如下:

First option: 
INSERT INTO `table` `field1` = ?, `field2` = ?; 

Second option: 
INSERT INTO `table` (`field1`, `field2`) VALUES (?, ?); 

而且,而是采用mysqli_query(),你需要使用mysqli_prepare(),mysqli_bind_param()和mysqli_execute()。您可以在这里查看更多关于它们语法的数据:http://php.net/manual/en/mysqli.prepare.php

至少,您可以使用mysqli_real_escape_string()函数来正确地转义和检查输入。您可以点击这里这个函数的文档:http://php.net/manual/en/mysqli.real-escape-string.php

+0

我很抱歉,我一定是误解你在说什么?我的插入代码是INSERT INTO PublicNoticesTable(url,county,paperco,date,notice,id)VALUES“。$ queryString',你可以看到我将括号中的字段包围起来,最后我不想复制和粘贴$ queryString变量的例子,但你可以参考我的问题来看一个例子,它在一行中很混乱,但它显示的值设置为(值,价值,价值,价值,价值),然后最终设置以分号结尾,我会尝试将括号添加到$ queryString中,看看是否有效。 – Pixelknight1398

+0

您已经包围了字段名称,但没有字段值,正如我在所有示例中所建议的。 –

+0

我按照你的建议做了,你可以在B的评论中看到查询字符串的结果。Desai的回答 – Pixelknight1398

0

你的代码是正确的。只需要添加()周围查询字符串 阿克索你需要从查询字符串结束删除;。 SO删除以下else条件您查询像

else{ 
    $queryString .= ";"; 
} 

变化:

$query = "INSERT INTO PublicNoticesTable (url, county, paperco, date, notice, id) VALUES (" . $queryString . ")"; 

此外,它建议使用准备语句从SQL注入

+0

好吧,我做了你所建议的改变,我得到一个新的错误,显示为'失败:你的SQL语法有错误;检查与您的MySQL服务器版本相对应的手册,以查找正确的语法,以便在每行失败的查询的第1行'''附近使用。然后,最终不再有成功值,现在失败,出现此错误:'失败:操作数应该包含1列(s)' – Pixelknight1398

+0

您是否删除了这个其他部分? 'else {$ queryString。=“;”; }'? –

+0

是的,我已经这样做了,我评论了一下。 – Pixelknight1398