Upsert
在PG中是一个很棒的新东西(我们最近更新了数据库以使用它),现在我们正在尝试在PHP中编写upsert适配器,以便使用起来很简单。
如果我们想要upsert,我们应该怎么做:
INSERT INTO {$this->_name} AS t ({$insertCols}) VALUES ({$insertVals})
ON CONFLICT {$onConflict} DO UPDATE
SET {$updateVals}
WHERE {$updateWhere}
我们可以将它简化为更简单的功能,这在代码中更方便:
ModelTable()->getInstance()->getAdapter->upsert($data, $onConflict, $where);
//e.g.
ModelTable()->getInstance()->getAdapter->upsert(['name=>'Denis', 'age'=>36], '(name)', "name = 'Denis'");
在这种情况下,使用更方便,但问题是 - 我们必须知道限制列名称(名称)或限制名称本身将其放在$ onConflict变量中。上面示例中的变量'(name)'
。
如果要为该表添加另一个限制,或重命名旧表,则应更新与该表一起使用的整个php代码以添加新限制。
理想适配器应该看起来像常规更新适配器:
ModelTable()->getInstance()->getAdapter->upsert(['name=>'Denis', 'age'=>36], "name = 'Denis'");
因此,如果存在name = Denis
的行,则会更新,如果不存在,则应该创建。
所以问题是 - 如何在php中创建可以这样工作的adaper?我们知道应该更新哪一行的列名,因此应该可以构造ON CONFLICT ... DO UPDATE
句子。我想对任何冲突进行更新,与
try {
...insert
} catch (Exception $e) {
...update
}
我们现在正在使用。
谢谢。
答案 0 :(得分:0)
你想要实现upsert
的方式就像捕捉\Exception
一样意味着«如果插入不起作用,我会尝试更新。»承认这是一个真正缺乏控制权域名。您可能希望在与主键冲突时更新行,但在与示例相同的表中的唯一字段冲突时拒绝这些行。
冲突的原因属于模型,这些是明确实现为约束的业务规则。只有模型层知道它拒绝插入的原因并改为更新行。因此,无论域定义如何,它都不能是可以在所有表上调用的通用upsert命令。
这意味着这是ModelTable
实例,它知道记录与现有数据冲突的原因,就像它知道表结构一样(我猜你的例子)。