2011-11-30 49 views
2

我正在爲應用程序構建複製活動功能,並且我使用循環來遍歷所有使用php的選定行,獲取其ID並再次循環插入具有相同數據但具有一個更改的列值的新行。這是我目前的做法是完美的:使用php和mysql複製多個表中的行

<?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將行復制到元素表中。 新的腳本:

$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元素)沒有。這是因爲它選擇了舊廣告系列中的變體,並將舊ID插入到var列中,而不是以前插入的新ID。很明顯,這是因爲查詢是以這種方式構建的,但是如何從新變體中獲取ID而無需循環將它們插入到元素中。 (還是我妄想太多,我最初的做法是好的?)

爲了與我的問題更加清晰 - 我該怎麼做這沒有一個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 

對不起,我的語法錯誤(我剛剛工作,需要一個咖啡)

感謝很多:)

回答

0

不是很確定我明白你在問什麼,因爲事實上,你的問題包含了太多的原因信息。我會盡量回答只有你最後一個問題:

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 

再次,如果我錯過了點:)

所以你插入了一堆行,然後根據這些的ID的不苛刻,你想將它們插入到不同的表中?所以如果只有你,誰在使用這個系統,那麼簡單的方法就是將插入的行的ID取出來,例如,如果你知道插入行的數量,只需簡單地取最後n行即可。或者添加具有唯一ID的另一列,以便您只能從中獲取。然後,具有陣標識的,用冒號加入他們的行列,最後,您的查詢應該是這樣的:

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 IN($c_ids) AND e.var IN($v_ids) 

因此,在總結: -insert -Take插入的C IDS -insert -Take插入v IDS -joinçIDS -join v IDS 次使用的查詢

而且我不知道該查詢如何處理這樣的事情:

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) 

我真的希望它不會逐一插入1000行。然而,如果它(並且我猜你對此有偏執),請在php中使用連接,這樣可以減少發送到sql的文本數量,尤其是調用的查詢量。如果行數很高,花費的時間將會非常可觀。

0

如果這是你需要遵循然後按我來說,這是更好地定義一個函數,該函數使用內部的經常性進程你的邏輯。由於函數是預編譯的,因此執行速度會很快。並在前端調用該函數。

+0

我不確定我是否完全理解你的答案。你是否建議將此腳本添加到函數中?我真的沒有看到真正的價值,因爲它只會在應用程序的一個地方使用(對於AJAX調用),因此它不是位於不同位置的「可重用」腳本。對不起,如果我沒有讓自己清楚,但問題是:當不知道新的變體ID和不使用PHP循環時,如何複製元素表中的行。 – Ignas

相關問題