如果不存在则插入:Doctrine DBAL

3

我正在使用Symfony2框架和Doctrine DBAL,将一些数据插入到MySQL数据库中。插入操作大致如下(简化版):

$conn->insert('sometable', array(
        "col1"     => $data1,
        "col2"     => $data2,
        "col3"     => $data3
));

我希望实现的功能类似于普通SQL-has。例如:INSERT IGNORE,如果不存在就进行插入。但是使用DBAL能否实现这样的功能?
请注意,我在这里没有使用对象。
编辑:请注意,我没有使用对象,而是使用了DBAL所描述的数组插入方法。
编辑2:我尝试使用建议的try-catch来解决问题,它似乎工作得很好,除了一个问题。即使没有添加新行,数据库也会自动增加主键。
以下是我使用的代码:
    try{
        $conn->insert('sometable', array(
            "col1"     => $data1,
            "col2"     => $data2,
            "col3"     => $data3
       ));
   } catch( \Exception $e) {
          switch (get_class($e)) {
               case 'Doctrine\DBAL\DBALException':
                   // No problems here. Just means that the row already existed.
                   break;
               default:
                   $this->get('logger')->error("(ERROR in ".__METHOD__.", @Row: ".(__LINE__)."): DB-error! error: ".$e->getMessage());
                   break;
          }
  }

我还必须为表格做一个多行唯一索引,因为我需要检查所有列是否相同。也就是说,如果整行与我们要插入的行完全相同。

所以……除了每次尝试-插入-捕获时自动增加值会不断上升之外,它工作得很好。我不认为这是一个真正的问题,但浪费数字感觉很愚蠢.. :D


1
嗨,请尝试访问此链接:https://dev59.com/bEzSa4cB1Zd3GeqPiwBA - Auris
@Auris 请注意,我并没有使用对象,而是使用了DBAL所描绘的数组插入方法。 - GotBatteries
1个回答

3

除了执行选择查询并尝试检索行之外,我不知道其他方法来完成这个操作,即:

$sql = "SELECT * FROM sometable WHERE ....";
$stmt = $conn->prepare($sql);
$stmt->bindParam(); //or bindValue...
$stmt->execute();

$exists = $stmt->fetch();

if(!$exists) {
    // insert or whatever..
} else {
    // do nothing? 
}

最终,您可能能够附加 事件 来为您完成此操作,但我不确定它是否适用于您的情况。
或者,您可以创建唯一约束,并在插入数据时进行 try/catch 处理。每当数据不唯一时,数据库将返回一个错误,并且您通常会收到 PDOException,尽管在 Doctrine 中,我认为使用了不同的名称(请检查 异常)。只需捕获该异常并对其不做任何处理即可。例如:
try {
    $conn->insert('sometable', array(
        "col1"     => $data1,
        "col2"     => $data2,
        "col3"     => $data3
    ));
} catch(PDOException $e) {
   // do nothing. 
}

是的,这是我迄今为止一直在使用的方法,但是使用了DBAL。首先进行检查,然后再插入(如果需要),但我希望能够在同一条命令中完成此操作。这将减少代码量,并且可能也不会花费太多时间。我一直在阅读DBAL文档,但是它...嗯...很糟糕。我找不到有关如何使用DBAL执行“INSERT IGNORE”的任何信息。 - GotBatteries
1
如果您可以在表中设置一个“唯一”列,那么您可以直接插入数据并执行try{} catch(PDOException $e){}或类似的操作。因此,每当数据存在时,您将只是捕获异常并不做任何处理? - tftd
嗯...那可能会有效...之后一定要尝试一下。谢谢你的提示! - GotBatteries

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接