1

、、という 3 つsales_orderのテーブルがあり、ON UPDATE = NO ACTION ON DELETE = NO ACTION に設定されているとします。sales_order_itemsinvoice

ここで、販売注文を削除できるようにする必要があります。しかし、他のテーブルに関係が存在する場合は、その販売注文が他の場所で使用されていることを意味し、削除を防ぐ必要があります。

例: sales_order_id = 34 があり、他のテーブルに存在することを確認したい。

以前は、以下のようなトランザクションを使用して同じことを達成しました

$db = new database();

//start transaction

$db->start_trans();

//try to delete the sales order with ID = 34
$db->exec( 'DELETE FROM SALES_ORDER WHERE ID = 34' );

//check transaction success or failure 

if( $db->trans_status() == true ){

 //THERE IS NO RELATION EXISTS
 //ROLLBACK
 $db->rollback_trans();

 #Soft Delete the record     
 $db->exec( 'UPDATE sales_order SET is_deleted = 1 WHERE id = 34' );

}else{

 //RELATION EXISTS FOR ID = 34 IN SOME OTHER TABLES
}

上記のコードは機能しますが、問題はsales_order_items. これはの子テーブルであるため、sales_order内容がある場合、トランザクションは失敗し、else 部分を実行しようとします。

しかし、実際sales_order_itemsにはのプロパティでsales_orderあり、その特定の sales_order を削除する必要があります (アイテムは気にしません)。

私はこのようなものを期待しています

$relations = $db->get_relation( 'sales_order.id', '34' );

期待される出力

array( 'sales_order_items','invoice','another_table' .... );

注: 上記は単なる例です。多数のテーブルがあり、各テーブルを調べてID 存在を確認することはできません。

4

2 に答える 2

0

良い答えを提供してくれたRevouaに感謝します。これは、私のニーズに合わせて少し修正されたバージョンです。もっと良い方法があれば修正してください。

function check_relation( $table_name , $table_column ,$table_value ){

        //Get relation tables
        $qry = "SELECT  table_name,
                column_name,
                referenced_table_name,
                referenced_column_name 
                FROM information_schema.KEY_COLUMN_USAGE
                WHERE REFERENCED_TABLE_SCHEMA = ?
                AND REFERENCED_TABLE_NAME is not null
                AND referenced_table_name = ?
                AND referenced_column_name = ?";

        $db = $this->crm->db;

        //database name
        $database = $db->dbprefix.$db->database;

        //predefined array to store table names
        $related_tables = array();

        //execute the query 
        $qry = $db->query( $qry , array( $database , $table_name ,$table_column ) );

        unset($database);

        //Make sure that query is success
        if( $qry != FALSE && $qry->row_count() > 0 ){

            //Get as array
            $result = $qry->to_array();
            unset($qry);

            foreach( $result as $result_item ){

                //Get count based on table_value
                $qry = "SELECT COUNT(*)as total FROM ".$result_item['table_name']." WHERE ".$result_item['column_name']." = ? and is_del = 0";
                $qry = $db->query($qry,array($table_value));

                if( $qry!= FALSE && $qry->row_count() > 0 ) {

                    $qry = $qry->to_array(1);

                    //There are some entries ..
                    if( intval($qry['total']) > 0 ){        
                        $related_tables[] = $result_item['table_name'];
                    }

                }


            }

            return $related_tables;

        }else{
            return $related_tables;
        }

    }

使用法:

$relation = $db->check_relation("SALES_ORDER","ID",34);

var_dump( $relation ) ==>

array( 'SALES_ORDER_ITEM','INVOICE' ... );

今はビジネスロジックに

if( empty( $relation )  ){

  // No relation exists

}elseif( in_array( 'invoice', $relation ) ){

   $message->set_message("Cannot delete Sales Order, Invoice exists.");

}else ...
于 2013-07-24T08:34:45.357 に答える