A
A
Andryushkov Konstantin2014-12-26 03:21:17
MySQL
Andryushkov Konstantin, 2014-12-26 03:21:17

How to store multiple rows of data in mysql in one DB call (Yii)?

Good time of the day.
I don’t understand the database well, but I understand that it’s better to transfer all the data in one request than to drive it because of each new line. I make a menu based on site page traffic statistics, using the Yandex Metrics API, and save data on the number of views in the database. I receive json of all data at once. Prompt how it is correct to organize saving them in a DB. So far, I've done line-by-line saving, but I think that this is not very competent, so don't swear.

public function actionIndex()
  {
      // Получение json из API Яндекса
    $dataProvider=new CActiveDataProvider('Statistic');
        $today = date("Ymd");
        $since = time();
        $since = $since - 172800;
        $since = date("Ymd", $since);
        $metrika_url = "http://api-metrika.yandex.ru/stat/content/popular.json?date1=$since&date2=$today&id=********&pretty=1&per_page=20&reverse=1&oauth_token=********";
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $metrika_url);
        curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
        $metrika = curl_exec ($ch);
        curl_close ($ch);
        $metrika = json_decode($metrika);

        // Сохранение данных в БД
        for($i=0; $i < count($metrika->data); $i++){
            $id = $metrika->data[$i]->url;
            $id = substr($id,23);
            if(is_numeric($id)){
                $model = $this->loadModel($id);
                $model->count_views = $metrika->data[$i]->page_views;
                $model->save();
            }
            else {
                continue;
            }
        }
    $this->render('index',array(
      'dataProvider'=>$dataProvider,
    ));
  }

        public function loadModel($id)
  {
    $model=Statistic::model()->findByPk($id);
    if($model===null)
      throw new CHttpException(404,'The requested page does not exist.');
    return $model;
  }

Here is an example of the received data
[data] => Array
(
[0] => stdClass Object
(
[page_views] => 152
[exit] => 20
[url] => test.ru
[id] => 76422421722242948292
[entrance] => 17
)
[1] => stdClass Object
(
[page_views] => 37
[exit] => 0
[url] => test.ru/page/62
[id] => 28851019514143479240
[entrance] => 1
)
[2] => stdClass Object
(
[page_views] => 37
[exit] => 1
[url] => test.ru/page/61
[id] => 31982420509639932555
[entrance] => 0
)

Answer the question

In order to leave comments, you need to log in

3 answer(s)
M
melnikov_m, 2014-12-26
@melnikov_m

$connect = Yii::app()->db;
$connectBuilder = $connect->schema->commandBuilder;
$attributes - массив с данными.
$connectBuilder->createMultipleInsertCommand('table', $attributes)->execute();

www.yiiframework.com/doc/api/1.1/CDbCommandBuilder...

A
Arman, 2014-12-26
@Arik

You need to get a request like this:
And the loop should at least do this if it doesn’t work / don’t like it through foreach

// Сохранение данных в БД
for($a = 0, $b = count($metrika->data); $a < $b; $a++){
// ....
}

A
Artem, 2014-12-26
@ArtemSV

As far as I understand, only one field needs to be updated, this can be implemented with one sql query.
Something like:

$query = "UPDATE `table_name` SET `count_views` = CASE";
$counter = 0;
if(is_numeric($id)){
    $query .=" WHEN `id` = ".$id." THEN '".$metrika->data[$i]->page_views."' ";
    $counter++;
} 
if ($counter) {
    $query .="  ELSE `count_views` END ;"
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question