Я создаю функцию копирования кампании для приложения, и я использовал циклы для просмотра всех выбранных строк с помощью php, получения их идентификаторов и повторения цикла для вставки новых строк с такими же данными, но с одной измененной значение столбца Это мой текущий подход, который отлично работает:
<?php
$id = Url::find('id');
//Copy campaign row
$cid = $this->Db->Query("
INSERT INTO campaigns (`user_id`, `tid`, `featured`, `opt`, `title`, `uri`, `cpi`, `payout`, `cat`, `domain`, `created`, `disabled`, `completed`, `featured_pos`)
SELECT `user_id`, `tid`, `featured`, `opt`, CONCAT(`title`,' - Copy'), `uri`, `cpi`, `payout`, `cat`, `domain`, `created`, `disabled`, `completed`, `featured_pos` FROM campaigns WHERE id = :id
",array(':id' => array(DB::INT => $id)),true);
//Copy variants
$vars = $this->Db->selectAll(array('cid' => $id), 'variations');
if(!empty($vars)) {
for($i = 0; $i < count($vars); $i++) {
$old[] = $vars[$i]['id']; //Copy source
$vid[] = $this->Db->Query("
INSERT INTO variations (`ordering`, `disabled`, `cid`, `height`, `width`, `bgcolor`, `head`,`title`, `keywords`, `description`, `link`)
SELECT `ordering`, `disabled`, :cid, `height`, `width`, `bgcolor`, `head`, `title`, `keywords`, `description`, `link` FROM variations WHERE id = :id
",array(
':id' => array(DB::INT => $vars[$i]['id']),
':cid' => array(DB::INT => $cid)
),true);
}
}
//Copy elements
if(isset($vid)) {
for($i = 0; $i < count($vid); $i++) {
$this->Db->Query("
INSERT INTO elements (`name`, `var`, `type`, `left`, `top`, `width`, `height`, `z-index`, `html`, `css`)
SELECT `name`, :vid, `type`, `left`, `top`, `width`, `height`, `z-index`, `html`, `css` FROM elements WHERE var = :id
",array(
':vid' => array(DB::INT => $vid[$i]),
':id' => array(DB::INT => $old[$i])
),true);
}
}
echo "OK";
?>
Однако я уверен, что это не лучший подход, поскольку он выполняет слишком много запросов. Я обновил скрипт, но не могу понять, как скопировать строки в таблицу элементов с новыми идентификаторами новых вариантов.
Новый скрипт:
$id = Url::find('id');
$cid = $this->Db->Query("
INSERT INTO campaigns (`user_id`, `featured`, `title`, `domain`, `created`, `disabled`, `featured_pos`)
SELECT :user, `featured`, CONCAT(`title`,' - Copy'), `domain`, `created`, `disabled`, `featured_pos` FROM campaigns WHERE id = :id
",array(':id' => array(DB::INT => $id), ':user' => array(DB::INT => $this->session->user['id'])),true);
//Copy variants
$this->Db->Query("
INSERT INTO variations (`ordering`, `disabled`, `cid`, `height`, `width`, `bgcolor`, `head`,`title`, `keywords`, `description`, `link`)
SELECT `ordering`, `disabled`, :id, `height`, `width`, `bgcolor`, `head`, `title`, `keywords`, `description`, `link` FROM variations WHERE cid = :oid
",array(
':id' => array(DB::INT => $cid), //new id
':oid' => array(DB::INT => $id) //old id
),true);
$this->Db->Query("
INSERT INTO elements (`name`, `var`, `html`, `type`)
SELECT e.name, v.id, e.html, e.type FROM elements AS e, variations AS v
WHERE v.cid = :cid AND e.var = v.id
",array(
':cid' => array(DB::INT => $id)
),true);
Первые 2 запроса работают как положено, однако последний (элементы INSERT INTO) - нет. Это потому, что он выбирает варианты из старой кампании и вставляет в столбец var старые идентификаторы вместо ранее вставленных новых. Очевидно, это потому, что запрос построен таким образом, но как мне получить идентификаторы из новых вариантов без цикла, чтобы вставить их в элементы.
(Или я слишком много параноик, и мой первоначальный подход в порядке?)
Чтобы быть более понятным с моим вопросом - как мне сделать это без цикла php:
INSERT INTO elements (`name`, `var`, `html`, `type`)
SELECT e.name, (new v.id from the previous query and not the same one as in WHERE clause), e.html, e.type FROM elements AS e, variations AS v
WHERE v.cid = :cid AND e.var = v.id
Извините за мои грамматические ошибки (я только что приступил к работе и мне нужен кофе)
Большое спасибо:)