簡體   English   中英

使用php和mysql從多個表復制行

[英]Copying rows from multiple tables with php and mysql

我正在為一個應用程序構建復制活動功能,而我的操作方式是使用循環使用php瀏覽所有選定的行,獲取其ID並再次循環以插入具有相同數據但列值已更改的新行。 這是我目前的最佳方法:

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

$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);

前兩個查詢按預期工作,但是最后一個(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

抱歉我的語法錯誤(我剛上班需要喝杯咖啡)

非常感謝 :)

不太確定我是否理解您的要求,因為事實上,您的問題中包含太多的原因信息。 我將嘗試僅回答您的最后一個問題:

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的另一列,因此您只能從中獲取。 然后將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-獲取插入的c id -insert-獲取插入的v id -join c ids -join v id-使用查詢

而且我不知道查詢如何與以下內容一起工作:

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中使用joins,這樣可以減少發送到sql的文本量,尤其是減少調用的查詢量。 如果行數很多,那么花費的時間將非常可觀。

如果這是您需要遵循的常規過程,那么按照我的觀點,最好定義一個函數,並在該函數內部使用您的邏輯。 由於函數是預編譯的,因此執行速度很快。 而在前端只需調用該函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM