Как вставить многомерный массив в базу данных с заменой существующих строк?

Аватар пользователя engenes engenes 25 апреля 2019 в 15:09

есть массив такого вида

<?php<?
    $taskdata = array(
        0 => array(
            'pageid' = 56454,
            'taskid' = 545,
            'uid' = 24,
            'weight' = 0
        ),
        1 => array(
            'pageid' = 56454,
            'taskid' = 787,
            'uid' = 24,
            'weight' = 1
        ),
        2 => array(
            'pageid' = 56454,
            'taskid' = 154,
            'uid' = 24,
            'weight' = 2
        ),
        3 => array(
            'pageid' = 56454,
            'taskid' = 9,
            'uid' = 24,
            'weight' = 3
        ),
        4 => array(
            'pageid' = 56454,
            'taskid' = 219,
            'uid' = 24,
            'weight' = 4
        ),
        5 => array(
            'pageid' = 56454,
            'taskid' = 87,
            'uid' = 24,
            'weight' = 5
        ),
        6 => array(
            'pageid' = 56454,
            'taskid' = 4878,
            'uid' = 24,
            'weight' = 6
        ),        
    )?>

как вставить этот массив в таблицы, каждый дочерний массив является новой строкой, а при совпадении строки, по значениям полей
pageid, taskid, uid заменить ее (строку)

то есть если я вставляют текущий массив а у меня в таблице есть две строки

есть есть две строки с такими значениями:

id | pageid | taskid | uid | weight
.. .. ... ... .....
15 | 56454 | 4878 | 24 | 0
16 | 56454 | 219 | 24 | 10

то они должны замениться значениями из массива, а остальные значения должны просто вставиться в таблицу.

читал про Merge queries using db_merge

но не нашел чтобы там можно было многомерный массив за один запрос добавить.
Для db_update, есть информация но для Merge нет..

Может быт кто то делал что то подобное, ситуация то довольно распространенная

нашел что можно сделать как то так

<?phpdb_merge('table')->key('col1')->fields($taskdata);?>

но как я понял тут сравнивается по одной колонке а мне нужно по сочетанию из трех

Лучший ответ

Аватар пользователя engenes engenes 25 апреля 2019 в 18:08
2

1 создаём уникальный индекс по тем полям по которым будем проводить сравнение.
Делается это во вкладке структура в phpmyadmin.
Выбираем отмечаем те поля в таблице, по которым будем сравнивать.

Нажимаем на кнопку "уникальный"
Либо другой вариант просто выполняем запрос

CREATE UNIQUE INDEX idx_mat_usr ON material_weights (pageid, tasked, uid)

Это действие выполняется однократно, для подготовки таблицы

2. Выполняем запрос, в который вставляем строку собранную из нашего массива:

<?phpdb_query("INSERT INTO material_weights (pageid, tasked, uid)
VALUES (54454,4878,24,0), (54454,219,24,10),... 
ON DUPLICATE KEY UPDATE weight = VALUES(weight)")?>

Таким образом все значения из массива будут вставляться одним запросом а те которые будут совпадать, перейдут к следующему этапу:
ON DUPLICATE KEY UPDATE weight = VALUES(weight)
В строке где наш ключ созданный из комбинации трех полей совпадает, произойдёт замена поля weight значением из собранной строки.

Комментарии

Аватар пользователя ivnish ivnish 25 апреля 2019 в 15:16

А почему бы не использовать поле id в качестве уникального идентификатора? Проверяйте если строка с таким id уже есть, то используйте update, если нет, то insert

Аватар пользователя engenes engenes 25 апреля 2019 в 15:26

у меня не может быть уникального идентификатора)))
уникальным является сочетание pageid,taskid,uid то есть если с массива прилетает элемент с такими же значениями, то строка должна замениться

Аватар пользователя bumble bumble 25 апреля 2019 в 16:14

Вставить - можно:

INSERT INTO TABLE (col1, col2) VALUES (val1, val2)

Вставить с проверкой и обновлением в случае существования - нельзя.

Аватар пользователя engenes engenes 25 апреля 2019 в 18:08
2

1 создаём уникальный индекс по тем полям по которым будем проводить сравнение.
Делается это во вкладке структура в phpmyadmin.
Выбираем отмечаем те поля в таблице, по которым будем сравнивать.

Нажимаем на кнопку "уникальный"
Либо другой вариант просто выполняем запрос

CREATE UNIQUE INDEX idx_mat_usr ON material_weights (pageid, tasked, uid)

Это действие выполняется однократно, для подготовки таблицы

2. Выполняем запрос, в который вставляем строку собранную из нашего массива:

<?phpdb_query("INSERT INTO material_weights (pageid, tasked, uid)
VALUES (54454,4878,24,0), (54454,219,24,10),... 
ON DUPLICATE KEY UPDATE weight = VALUES(weight)")?>

Таким образом все значения из массива будут вставляться одним запросом а те которые будут совпадать, перейдут к следующему этапу:
ON DUPLICATE KEY UPDATE weight = VALUES(weight)
В строке где наш ключ созданный из комбинации трех полей совпадает, произойдёт замена поля weight значением из собранной строки.

Аватар пользователя bumble bumble 25 апреля 2019 в 19:19

Круто!
Только уточните что это для мускуля, и приведите пример с поддерживаемым (программным) созданием индексов.