0

そのため、複数のテーブルから削除しようとしています (このシナリオでは 6)。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);

これをどのように単純化できますか?

4

4 に答える 4

0

クエリの送信に取り組む代わりに、mysqlデータベースにいくつかのトリガーを設定する必要があります。

delimiter $
CREATE TRIGGER Trigger_Name BEFORE DELETE ON some_table
FOR EACH ROW BEGIN DELETE FROM some_other_table WHERE some_id = NEW.id;
終了$

これをPHPMYADMINのSQLに入れると、Trigger_Nameというトリガーが作成されます(実際には関係ありません)。

some_tableで削除関数を実行するたびに、所有しているIDを持つsome_other_tableの行が削除されます。

詳細については、 http://dev.mysql.com/doc/refman/5.0/en/create-trigger.htmlを参照してください。

于 2012-05-11T14:51:32.343 に答える
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-> query( "DELETE FROM quiz_answers WHEREquestion_id="。$q->id);

もう1つのオプション(許可がある場合)は、外部キーと「ONDELETECASCADE」を設定することです。http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html

そうしないと、データベースの構造を知らなければ、これ以上の推奨は困難になります。副選択を使用することもできますが、それでもカスケードが必要です。

別のオプションは、複数のフィールドに基づく主キーを含むようにDB構造を変更することです(たとえば、course_topic_dotpointsは "topic_id、badge_id、dotpoint_id"になります)。その後、一度にさらに削除できますが、これにはおそらくかなりの変更が必要です。 。

于 2012-05-11T05:10:14.200 に答える
0

さて、複数のテーブルから削除する関数を自分用に作成しました

    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.';
        }
    } 

使い方

これらはコントローラーメソッドのパラメーターです

$table  =   array('table1','table2','table3');
$condition  =   array('id'=>1,'2nd_condition'=>'blah');
$join_condition =   array(
                    'table1.column' =>  'table2.column',
                    'table1.column' =>  'table3.column'
                    );

これは完璧に機能します

于 2012-05-11T06:42:11.153 に答える
0
you need to SET FOREIGN_KEY_CHECKS = 0;
you can read more dev.mysql.com/doc/en/innodb-foreign-key-constraints.html
SET @BACKUP_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS; 
SET @@FOREIGN_KEY_CHECKS=0;

-- Do stuff here

SET @@FOREIGN_KEY_CHECKS=@BACKUP_FOREIGN_KEY_CHECKS;
SET @BACKUP_FOREIGN_KEY_CHECKS=NULL;
于 2012-05-11T05:26:34.607 に答える