Задать вопрос
BelyaevAnton
@BelyaevAnton
Делал сайты до того, как это стало мейнстримом...

Как отловить синтаксическую ошибку в SQL-запросе?

Привет, Тостеряне!

Пишу я себе спокойно скрипт парсинга стены сообщества ВК через VK Api на PHP+MySQL.
Bот уж второй день бьюсь головой о стену синтаксиса SQL. "Ошибка вроде бы есть, а вроде её нет".
Смотрите:
5c949795116a5132900221.jpeg

Что я делаю? - Забираю с API (wall.get) потоками по 100 записей посты, делаю из них длинные INSERT-запросы (id поста, date в UNIX, текстом и массивом с адресами фотографий) * (по 100 в каждом INSERT). - Всё это прекрасно! Тестовая стена 27000+ записей, разбивается на 270 потоков и погнал цикл. Но вот незадача. 269 потоков молодцы, а один осыпается на уровне SQL.

Да осыпается не явно. Если взять то место, на которое ругается mysql, и оставить из всего запроса только его - всё прекрасно отрабатывает. Если удалить часть запроса, на который ругается mysql - то ошибочной частью станет уже другая его часть:
5c949a0fc0486617503484.jpeg

Вот Вам php-код, если надо:

<?
set_time_limit(10000); // Разрешаем скрипту выполняться долго
//echo ini_get('max_execution_time');

include("_sqlconfig.php");

$communityID = "-64874860"; // Вводим ID сообщества

$token = file_get_contents('token.php');
$token = substr($token,3,-3); // Получаем token из token.php убрав по 3 символа с обоих сторон




function GetResponse($offset){ // Функция запроса wall.get на основе параметра порядкового номера записи с которой начинать выборку
    
    global $token;
    global $communityID;
    
    $params = array('owner_id'=>$communityID,'offset'=>$offset,'count'=>100,'filter'=>'owner','access_token'=>$token,'v'=>'5.87');
    $url = 'https://api.vk.com/method/wall.get?' . http_build_query($params);
    $response = json_decode(file_get_contents($url), true);
    
    return $response;    
}






function attachments_to_json($attachments){    // Функция создания JSON из вложений если они фотографии
    
    $attached_photos = false;

    if(!$attachments){ return "NULL"; }

    foreach($attachments as $att){
    
        if($att['type']=="photo"){
    
            foreach($att['photo']['sizes'] as $x){                    
                
                $w = $x['width'];
                $photo[][$w]=$x['url'];    
                
                $attached_photos = true;
            }
            
        }else{
            continue;
        }    
    }

    if($attached_photos){
        $attached_photos = json_encode($photo);
        return "'{$attached_photos}'";
    }else{
        return "NULL";
    }
}





function makeSQL($response){ // Функция создания из ответа от API SQL-запроса на добавление в базу

    global $SQL;

    $SQL = "INSERT INTO  `64874860` (
        `id` ,
        `post_id` ,
        `date` ,
        `text` ,
        `attachments`
        )
        VALUES (";
    
    foreach($response['response']['items'] as $post){

        global $SQL;

        //print "<br>ID поста:".$post['id'];
        //print "<br>Дата поста:".$post['date'];
        //print "<br>Текст поста:".$post['text']."<br>";
        $att = attachments_to_json($post['attachments']);        
        //echo "<br>Вложения:<br>".$att."<br><br><br>"; 

        $text = str_replace("'", "", $post['text']);
        $text = str_replace(")", "", $text);
        $text = str_replace("(", "", $text);

        $SQL = $SQL."'', {$post['id']},  {$post['date']},  '{$text}',  {$att}), (";
        
    }

    $SQL = substr($SQL,0,-3).";";

    return $SQL;    

}





$response = GetResponse(0); // Получаем первые 100 записей и информацию о общем их количестве
$SQL = makeSQL($response); // Делаем из первых 100 записей первый запрос в SQL

$wallCount = $response['response']['count'];
print "<b><u>На стене сообщества {$wallCount} записей.</b></u><br><br>";

//print $SQL;

print "<b>Поток 0: Читаем записи c 0 до 100:</b>";
if(mq($SQL)){ print "... OK<br>"; }else{ "... FUCK!"; }



$flows = ceil($wallCount/100); // Вычисляем количество потоков чтения стены (по 100)

for($i=1;$i!=$flows;$i++){    
    
    
    
    $offset = $i*100;   
    $x = $offset+100;

    print "<br><b>Поток {$i}: Читаем записи c {$offset} до {$x}:</b>";
    $response = GetResponse($offset);
    $SQL = makeSQL($response);    

    if(mq($SQL)){ print "... OK"; }else{ print "... FUCK!"; print "<br><br> >>".$SQL."<< <br><br>"; }

}









$final_sql_table_count = mfa(mq("SELECT COUNT(*) FROM `64874860`"));

$time = microtime(true) - $start; 
$time = round($time, 2);
echo "<br><br>Потребовалось времени на весь скрипт: ".($time)."сек.";
echo "<br>В SQL-таблице записей: ".$final_sql_table_count[0]." (в сообществе ".$wallCount." постов).";


?>


Помогите, а. Всем заранее жму руку за внимание и участие.
  • Вопрос задан
  • 223 просмотра
Подписаться 1 Простой 7 комментариев
Решения вопроса 1
dmitrydeco
@dmitrydeco
e25e0-clip-284kb.jpg?nocache=1 меня смущает экранирование, попробуй убрать обратный слеш
+ Стоит использовать PDO, чем пытаться отловить всё и вся через свои проверки
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Возможно, проблема в длине запроса.
https://dev.mysql.com/doc/refman/8.0/en/server-sys...
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы