2017-07-30 3 views
1

Je suis en train d'interroger de grandes quantités de données sur un serveur, voici mon code pour cela:requête MySQL ne parvient pas à exécuter

$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; 
} 

La variable $loopLength est dynamique et peut être des milliers ou potentiellement centaines de milliers . J'ai conçu cette fonction pour diviser ce nombre massif en un lot de requêtes plus petites car je ne pouvais pas télécharger toutes les données en même temps sur mon service d'hébergement partagé via GoDaddy. La variable $queryAmount représente la taille des requêtes les plus petites.

Voici un exemple de l'un des ensembles de valeurs qui est inséré dans la table: Ce sont les données d'un avis public que mon code a été récupéré dans la fonction 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'), 

Pour atteindre ces données, je l'exécute à travers une fonction qui parcourt la page et la saisit. Ensuite, je mets le code html page web grâce à cette fonction:

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

Ce qui me donne le contenu sans balises que vous voyez ci-dessus. Voici le problème.

La fonction s'exécute et tout semble juste dandy. Ensuite, la fonction (en fonction de la variable $queryAmount que je ne garde pas plus de 10 pour cause de problème) les sorties, comme vous pouvez le voir dans la fonction serait quelque chose comme ...

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 

La partie étrange est que lorsque J'ai de grandes quantités de données comme dire la variable $loopLength est comme 116. Le résultat sera sortie, "Échec: (erreur) Échec: (Erreur) Fai ... (Erreur) Succès. Donc, il interroge seulement le dernier ensemble de données Je ne suis pas sûr de la façon de résoudre ce problème et je veux un oeil frais.Cela peut m'aider s'il vous plaît.J'y ai travaillé pendant plusieurs heures en essayant de trouver une solution

Désolé pour faire de cette question une douleur dans le cul :(

EDIT:

J'ai changé le code de précédemment utiliser des déclarations préparées mysql et ce qui ne ... Voir ci-dessous:

$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); 
} 
Malheureusement, ce

est ce que je reçois de la sortie:

1 Row inserted. 0 Error: 

Pas d'erreur imprime réellement et la ligne est en inséré. Cependant, quand je navigue vers ma base de données, et regarde les valeurs qui ont été stockées .. Ils sont tous vides. Les sorties echo ceci:

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

Je sais donc que toutes les variables contiennent quelque chose, sauf pour la variable $notice qui est détruit par ma cleanData() fonction pour une raison quelconque.

+1

Fro m les commentaires sur les questions jusqu'à présent - je serais certainement utiliser des déclarations préparées et lier les valeurs. Si vos données proviennent de pages Web, les chances d'avoir des valeurs qui vont casser votre SQL si elles sont directement insérées sont très élevées, https://stackoverflow.com/questions/9629328/how-to-use-mysqli-prepared-statements-in -php peut aider. –

+0

J'ai fait quelques recherches sur les instructions préparées et lier les valeurs pour ne pas les insérer directement ... On dirait que ce serait un gros gâchis pour mon code essayant de générer dynamiquement l'instruction de requête et tout ça. Je suppose que je peux donner un coup de feu, mais comme je l'ai dit, je pourrais générer des milliers et des milliers de lignes de données, sans dire à quoi ressemblerait cette déclaration de liaison, sans parler de la requête elle-même. – Pixelknight1398

+0

Vous pouvez préparer l'instruction avec une insertion pour 1 ligne, puis chaque ligne de valeur de données que vous exécutez simplement l'instruction préparée avec la valeur d'une ligne de données. –

Répondre

0

Vous devez lier les données après l'extraction et avant de l'exécuter ...

$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

Merci, votre suggestion a résolu mon problème! :) Merci de m'avoir aidé, ça m'a pris une bonne minute. – Pixelknight1398

0

L'erreur principale que je peux voir sur votre requête, est la requête elle-même. Vous utilisez un INSERT INTO avec des champs et des valeurs séparés. Mais tu oublies d'utiliser la pharentesis sur les valeurs.

Rappelez-vous, l'utilisation d'INSERT INTO sont les suivantes:

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

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

De plus, rappelez-vous d'échapper à tous les domaines et de la valeur pour éviter d'autres erreurs: Exemple:

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

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

Si vous utilisez pilote mysqli, pour plus de sécurité, vous pouvez utiliser des instructions préparées, pour obtenir vos valeurs automatiquement échappées. Dans ce cas, la syntaxe de la requête sont les suivantes:

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

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

En outre, au lieu d'utiliser mysqli_query(), vous devez utiliser mysqli_prepare(), mysqli_bind_param() et mysqli_execute(). Vous pouvez vérifier plus de données sur leur syntaxe ici: http://php.net/manual/en/mysqli.prepare.php

Au moins, vous pouvez utiliser la fonction mysqli_real_escape_string() pour obtenir votre entrée correctement échappée et vérifiée. Vous pouvez vérifier la documentation de cette fonction ici: http://php.net/manual/en/mysqli.real-escape-string.php

+0

Je suis désolé, je dois mal comprendre ce que vous dites? Mon code d'insertion est 'INSERT INTO PublicNoticesTable (url, comté, paperco, date, notice, id) VALEURS". $ QueryString' que vous pouvez voir que j'ai entouré les champs entre parenthèses.Puis enfin je ne veux pas copier et coller l'exemple de variable $ queryString, mais vous pouvez renvoyer à ma question pour voir un exemple: elle est en désordre sur une seule ligne mais affiche la valeur définie comme (valeur, valeur, valeur, valeur, valeur), puis l'ensemble final se termine par un point-virgule Je vais essayer d'ajouter la parenthèse à $ queryString et voir si cela fonctionne. – Pixelknight1398

+0

Vous avez entouré les noms de champs, mais pas les valeurs de champs comme je l'ai suggéré dans tous mes exemples. –

+0

J'ai fait ce que vous avez suggéré et vous pouvez voir les résultats de la chaîne de requête dans les commentaires de la réponse de B. Desai – Pixelknight1398

0

Votre code est correct. Juste vous devez ajouter() querystring Vous devez également supprimer ; à partir de la fin de la chaîne de requête. retirer SO condition suivante autre

else{ 
    $queryString .= ";"; 
} 

changement que vous requête comme:

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

En outre, il convient d'utiliser instructions préparées pour empêcher des injections sql

+0

Ok, donc j'ai fait les changements que vous avez suggérés et j'ai reçu une nouvelle erreur comme 'Failed: Vous avez une erreur dans votre syntaxe SQL; consultez le manuel qui correspond à votre version du serveur MySQL pour la bonne syntaxe à utiliser près de ')' à la ligne 1' pour chaque requête échouée. Et puis il n'y a plus de valeur de succès à la fin c'est maintenant un échec avec cette erreur: 'Failed: l'opérande devrait contenir 1 colonne (s)' – Pixelknight1398

+0

Avez-vous supprimé cette partie else? 'else { $ queryString. ="; "; } '? –

+0

Oui, je l'ai fait, je l'ai commenté. – Pixelknight1398