2012-05-11 12 views
0

このシナリオでは、複数のテーブルから削除しようとしています。私はINNER JOINSを使用して、1つのクエリですべての行を削除しようとしましたが、動作させることができませんでした。複数のテーブルから削除

ここに私の嫌な仕事は周りです:

 // Delete course and everything linked to it (topics, badges, dotpoints, questions & answers) 
     $topic = $this->db->query("SELECT * FROM course_topics WHERE course_id = ".$row_id);  
     foreach ($topic->result() as $t) 
     { 
      $badge = $this->db->query("SELECT * FROM course_topic_badges WHERE topic_id = ".$t->id);  
      foreach ($badge->result() as $b) 
      { 
       $dotpoint = $this->db->query("SELECT * FROM course_topic_dotpoints WHERE badge_id = ".$row_id); 
       foreach ($dotpoint->result() as $d) 
       { 
        $question = $this->db->query("SELECT * FROM quiz_questions WHERE dotpoint_id = ".$d->id); 
        foreach ($question->result() as $q) 
        { 
         $answer = $this->db->query("SELECT * FROM quiz_answers WHERE question_id = ".$q->id); 
         foreach ($answer as $a) 
         { 
          $this->db->query("DELETE FROM quiz_answers WHERE question_id = ".$q->id); 
         } 
         $this->db->query("DELETE FROM quiz_questions WHERE dotpoint_id = ".$d->id); 
        } 
        $this->db->query("DELETE FROM course_topic_dotpoints WHERE badge_id = ".$b->id); 
       } 
       $query = $this->db->query("DELETE FROM course_topic_badges WHERE topic_id = ".$t->id); 
      } 
      $query = $this->db->query("DELETE FROM course_topics WHERE course_id = ".$row_id); 
     } 
     $query = $this->db->query("DELETE FROM courses WHERE id = ".$row_id); 

どのように私はこれを簡素化することができますか?

+0

"削除"が互いにどのように関係しているかを英語で説明できますか?さもなければ、それらが*関連していない*場合 - 別の "削除"ステートメントはあなたの最善の策です。 – paulsm4

+1

カスケード削除を使用したいくつかの外部キーの関係は、***本当に***あなたを助けます。 – Perception

答えて

0

あなたはこのビットを簡素化することができます。

$answer = $this->db->query("SELECT * FROM quiz_answers WHERE question_id = ".$q->id); 
foreach ($answer as $a) 
{ 
    $this->db->query("DELETE FROM quiz_answers WHERE question_id = ".$q->id); 
} 

単に ます$ this-> DB->クエリ(。$ Q-> ID "question_id = quiz_answers。DELETE FROM")へ。

他のオプション(許可を得ている場合)は、外部キーと "ON DELETE CASCADE"を設定することです。 http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html

それ以外の場合は、データベースの構造を知らなくても、それ以上のものを受け入れることは難しいでしょう。あなたはサブ選択を使用することができますが、まだいくつかのカスケードが必要です。

もう1つの方法は、複数のフィールドに基づいて主キーを含むようにDB構造を変更することです(course_topic_dotpointsは "topic_id、badge_id、dotpoint_id"となります)。公正な変化のビット。

+0

DB構造をどのようにして主キーを含むように変更できますか? – Sneaksta

+0

こちらをご覧ください:http://weblogs.sqlteam.com/jeffs/archive/2007/08/23/composite_primary_keys.aspxそれはかなりうまく説明しています。 – Robbie

+0

うわー。これはちょうど私の目を開いた。本当にありがとう! – Sneaksta

0
you need to SET FOREIGN_KEY_CHECKS = 0; 
you can read more dev.mysql.com/doc/en/innodb-foreign-key-constraints.html 
SET @[email protected]@FOREIGN_KEY_CHECKS; 
SET @@FOREIGN_KEY_CHECKS=0; 

-- Do stuff here 

SET @@[email protected]_FOREIGN_KEY_CHECKS; 
SET @BACKUP_FOREIGN_KEY_CHECKS=NULL; 
0

まあ、私はここで複数のテーブル から削除されます自分のための関数を作成しているが、それは、コントローラのメソッドが

$table = array('table1','table2','table3'); 
$condition = array('id'=>1,'2nd_condition'=>'blah'); 
$join_condition = array(
        'table1.column' => 'table2.column', 
        'table1.column' => 'table3.column' 
        ); 
をパラメータであり、どのように

これらを使用するように

function delete_multiple_rows($table , $condition , $join_condition) 
    { 
     $table_count = count($table); 
     $join_count  = count($join_condition) + 1; 

     if($table_count == $join_count) 
     { 
      if(count($condition)>0) 
      { 
       $delete_query = 'DELETE '. implode(' , ',$table) .' FROM '.$table[0]; 

       $counter = 1; 
       foreach($join_condition as $key => $value) 
       { 
        $delete_query .= ' LEFT JOIN ' . $table[$counter] . ' ON ' . $key . ' = ' . $value; 
        $counter++; 
       } 

       $condition_counter = 1; 

       foreach($condition as $key => $value) 
       { 
        if($condition_counter > 1) 
        { 
         $delete_query .= ' AND '; 
        }else{ 
         $delete_query .= ' WHERE '; 
        } 
        $delete_query .= $key . ' = ' . $value; 
        $condition_counter++; 
       }   
       $delete_query;    
       $this->db->query($delete_query); 

      }else{ 
       echo 'This query requires at least 1 where condition.'; 
      }  
     }else{ 

      $table_count = count($table) - 1; 
      echo 'At least ' . $table_count . ' join conditions must be provided.'; 
     } 
    } 

です

これが完璧です

0

クエリを送信する代わりに、おそらくmysqlデータベースにいくつかのトリガを設定する必要があります。 $
区切り

は がsome_id = NEW.id some_other_table。DELETE FROM BEGIN FOR EACH ROWのsome_table
ON DELETE BEFOREトリガーTRIGGER_NAMEを作成します。
ENDのphpMyAdminであなたのSQLで、それはTRIGGER_NAME(実際には関係ありません)と呼ばれるトリガーを作成しますことを入れて$

some_tableでdelete関数を実行するたびに、some_other_tableの行があなたのIDで削除されます。

詳しくはhttp://dev.mysql.com/doc/refman/5.0/en/create-trigger.htmlをお読みください。

+0

うわー。ありがとう!私はこれを調べます! – Sneaksta

+0

@Sneakstaあなたは歓迎します、言及すべきことは、あなたはトリガーを使って連鎖反応を起こすことができるということです。影響を与えるテーブルbのトリガとテーブルbのトリガがテーブルcに影響を与える場合テーブルaに送信されたクエリは、テーブルbおよびcに影響する可能性があります。 –

+0

ヘッドアップをありがとう。 – Sneaksta

関連する問題