以编程方式获取表mysql之间的关系

时间:2013-07-24 06:26:45

标签: php mysql foreign-keys

假设我有3个表sales_ordersales_order_itemsinvoice并设置ON UPDATE = NO ACTION ON DELETE = NO ACTION。

现在我需要有能力删除销售订单。但如果任何其他表中存在关系,则表示该销售订单在其他地方使用,我需要阻止删除。

例如:我有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_itemssales_order的属性,我需要删除特定的sales_order(不关心项目)。

我期待这样的事情

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

预期产出

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

注意:以上只是一个示例,我有多个表格,并且无法检查每个表格并检查ID是否存在。

2 个答案:

答案 0 :(得分:2)

select * from information_schema.table_constraints
where constraint_schema = DATABASE();

select * from information_schema.key_column_usage
where constraint_schema = DATABASE();

SQLFIDDLE

答案 1 :(得分: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 ...