2015-05-26 10:19:32 5166次浏览 6条回答 0 悬赏 10 金钱

我有a表和b表,他们有关联关系,b表是a表的外表,当我删除b中的内容时,会报代码级别的错误,那我怎样通过异常抛出来捕获异常,而不是报代码级别的错误?

以下是代码:

public function actionRequirementDelete($id,$page)
{
    $page = $page + 1;
    $requirement_data = Requirement::model()->findByPk($id);
    
    $transaction = $requirement_data->dbConnection->beginTransaction();
    try{
        if($requirement_data->delete()){
            $this->redirect(array('/user/employer','page'=>$page));
        }else{
            throw new Exception("订单删除失败");
        }
        $transaction->commit();
    }catch (Exception $e){
        $transaction->rollback();
        echo $e->getMessage();
    }
}

最佳答案

  • lxepoo 发布于 2015-05-26 10:30 举报

    你的这个需求,其实有好几种解决方式:

    1.是否一定需要报错?是否可以考虑在数据库里设置一下外键删除时的动作,比如CASCADE ?

    2.如果按你说的,你需要删除时判断是否有从属数据,那么你应该先判断从属数据是否存在,而不是通过异常去处理,因为异常出现的可能性很多,不一定是因为存在从属数据导致。

    3.我看到了你的异常捕获,

    catch (Exception $ex) {
        $transaction->rollBack();
    ...
    

    这种形式是正确的,但是你的思路错误,你认为delete()返回非true值时应该抛出一个异常,但是事实上delete()方法在删除报错时,内部已经先一步抛出了异常,也就是说,你的throw new Exception("订单删除失败");应该是不会触发的。

    1 条回复
    回复于 2015-05-26 11:05 回复

    恩,也只能先判断是否有数据依赖,没有再删除,有的话就禁止删除

  • 回答于 2015-05-26 10:22 举报

    心有余而力不足,唉,不会

    1 条回复
    回复于 2015-05-26 10:22 回复
    CDbCommand 无法执行 SQL 语句: SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`yfp`.`yfp_order_employer`, CONSTRAINT `FK_orders_requirement` FOREIGN KEY (`requirement_id`) REFERENCES `yfp_requirement` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION). The SQL statement executed was: DELETE FROM `yfp_requirement` WHERE `yfp_requirement`.`id`=15
    

    这是异常报错

    因为是删除带有外键的内容所以报错,但是delete方法为什么不发挥false,而是数据库报错?

  • 回答于 2015-05-26 10:23 举报

    自定义一个exception 比如UserException 或者OrderException等等,然后只捕获这个异常 ,其他的异常让系统处理去吧

    2 条回复
    回复于 2015-05-26 12:29 回复

    你这个和异常关系不大,当然,对于用户友好的异常信息,你还是需要自定义异常,然后去捕获,你这个主要的还是,设置好外键约束,父表删除的时候 子表也会被删除

    回复于 2015-05-26 12:53 回复

    恩,数据表的设计确实是关键

  • 回答于 2015-05-26 10:34 举报

    php的错误和异常不是一个统一的概念,php有的错误是无法捕获的,比如致命错误和编译错误等,如果抛出的是这两种错误,你没办法。如果抛出的是警告、提醒等,好像通过设置是可以通过CException捕获的。

    3 条回复
    回复于 2015-05-26 10:46 回复

    把外键关系设计好才是正途,这些只是奇巧淫技。

    回复于 2015-05-26 11:04 回复

    恩,这个设计就是为了防止删除掉依赖数据,我才设置了外键,不能删除,依赖数据,在删除依赖数据的时候要报错,是自定义的用户报错,不应该是代码级别的报错呀。

    回复于 2015-05-26 11:17 回复

    不删除依赖数据,那删除主数据也是不对的,这样就背离了外键确保数据‘完整性“的初衷。你可以不用物理删除数据,逻辑删除就好。

  • 回答于 2015-05-26 10:37 举报

    可以先做unlinkAll,把有外键依赖的关系表中的数据先删除,类似

    $requirement_data->unlinkAll('employer', true); // employer是定义的表yfp_order_employer关联名
    $requirement_data->delete();
    
    3 条回复
    回复于 2015-05-26 10:40 回复

    如果不想删除,只要将unlinkAll的第二个参数改成false就行了,yfp_order_employer的外键字段会置null

    回复于 2015-05-26 11:02 回复

    恩,但是如果这样的话,那么,依赖他的数据不就不完整了吗?

    回复于 2015-05-26 11:19 回复

    恩,一般没太大必要删数据,其实就加个字段标识记录删除状态就行了,不用数据库的delete操作,有时候可能还想追溯数据,除非数据量大到非删不可,这种情况下也可以通过定期删除无效数据来缓解。

  • 回答于 2016-04-05 23:54 举报

    可不可以关联修改?

您需要登录后才可以回答。登录 | 立即注册
yx
副总裁

yx 上海

注册时间:2014-09-11
最后登录:2020-08-03
在线时长:31小时46分
  • 粉丝22
  • 金钱5925
  • 威望45
  • 积分6685

热门问题