Don*_*sto 49
你可以这样抓住UniqueConstraintViolationException
:
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
// ...
try {
// ...
$em->flush();
}
catch (UniqueConstraintViolationException $e) {
// ....
}
Run Code Online (Sandbox Code Playgroud)
Pet*_*son 20
我使用此策略在flush()之后检查唯一约束,可能不是您想要的,但可能会帮助其他人.
当您调用flush()时,如果唯一约束失败,则抛出PDOException,代码为23000.
try {
// ...
$em->flush();
}
catch( \PDOException $e )
{
if( $e->getCode() === '23000' )
{
echo $e->getMessage();
// Will output an SQLSTATE[23000] message, similar to:
// Integrity constraint violation: 1062 Duplicate entry 'x'
// ... for key 'UNIQ_BB4A8E30E7927C74'
}
else throw $e;
}
Run Code Online (Sandbox Code Playgroud)
如果需要获取失败列的名称:
使用带前缀的名称创建表索引,例如.'独特_'
* @Entity
* @Table(name="table_name",
* uniqueConstraints={
* @UniqueConstraint(name="unique_name",columns={"name"}),
* @UniqueConstraint(name="unique_email",columns={"email"})
* })
Run Code Online (Sandbox Code Playgroud)
请勿在@Column定义中将列指定为唯一
这似乎用随机的一个覆盖索引名称......
**ie.** Do not have 'unique=true' in your @Column definition
Run Code Online (Sandbox Code Playgroud)
重新生成表后(可能需要删除它并重建),您应该能够从异常消息中提取列名.
// ...
if( $e->getCode() === '23000' )
{
if( \preg_match( "%key 'unique_(?P<key>.+)'%", $e->getMessage(), $match ) )
{
echo 'Unique constraint failed for key "' . $match[ 'key' ] . '"';
}
else throw $e;
}
else throw $e;
Run Code Online (Sandbox Code Playgroud)
不完美,但它有效......
如果在插入之前运行SELECT查询不是您想要的,则只能运行flush()并捕获异常.
在Doctrine DBAL 2.3中,您可以通过查看PDO异常错误代码(MySQL为23000,Postgres为23050)安全地理解唯一约束错误,该错误代码由Doctrine DBALException包装:
try {
$em->flush($user);
} catch (\Doctrine\DBAL\DBALException $e) {
if ($e->getPrevious() && 0 === strpos($e->getPrevious()->getCode(), '23')) {
throw new YourCustomException();
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
36790 次 |
最近记录: |