在db中处理重复错误的正确方法是什么

时间:2011-10-06 09:25:52

标签: php database atk4

我正在数据库中实现订阅。电子邮件必须是唯一的,因此我在数据库中有一个UNIQUE索引。我在我的页面init中有这个代码:

$f = $p->add('MVCForm');
$f->setModel('Account',array('name','surname','email'));
$f->elements['Save']->setLabel('Subscribe');

if($f->isSubmitted())
{
    try
    {
         $f->update();

         //More useful code to execute when all is ok :)

    }
    catch(Exception_ValidityCheck $v)
    {
        //Handles validity constraint from the model
        $f->getElement($v->getField())->displayFieldError($v->getMessage());
    }
    catch(SQLException $se)
    {
        //If I'm here there is a problem with the db/query or a duplicate email
    }
}

SQLException中唯一的信息是格式化的HTML邮件,这是检测错误是否来自重复条目的唯一方法吗?

3 个答案:

答案 0 :(得分:1)

这是一种方法:

https://github.com/atk4/atk4-web/blob/master/lib/Model/ATK/User.php#L95

虽然如果要对复制执行自定义操作,您应该将getBy移到模型之外,进入页面逻辑。

答案 1 :(得分:0)

正如@Col建议的那样,我们想要使用“insert ignore”。

$ form-> update()依赖于Model-> update(),然后依赖于DSQL类来构建查询。 DSQL执行support options,但模型会为您生成新的SQL。

Model-> dsql()为模型构建查询。它可以与几个“实例”一起运行,其中每个实例都有一个单独的查询。我并不特别喜欢这种方法,可能会添加新的模型类,但它现在可以使用。

看看这里: https://github.com/atk4/atk4-addons/blob/master/mvc/Model/MVCTable.php#L933

insertRecord()函数多次调用dsql('modify',false)来构建查询。你可以做的最简单的事情是:

function insertRecord($data=array()){
    $this->dsql('modify',false)->option('IGNORE');
    return parent::insertRecord($data);
}

插入记录后,Agile Toolkit将自动尝试加载新添加的记录。但是,它将使用相关条件。我认为,如果忽略记录,你将获得exception raised anyway。如果可能,请避免工作流程中出现异常。由于它们捕获回溯,因此异常是CPU密集型的。

唯一的方法可能是您完全重新定义insertRecord。它并不理想,但它可以让你按照自己的意愿进行单一查询。

我更喜欢用loadBy(或getBy)手动检查条件,因为它考虑了模型条件和连接。例如,您可能在表上进行了软删除,而MySQL键不允许您输入,Model和模型方式对于业务逻辑也更有意义。

答案 2 :(得分:-1)

为什么不想运行简单的选择来检查电子邮件是否已被占用?

或者让它INSERT IGNORE然后检查affected_rows