php - 如何以编程方式在 postgres 中使用 php 'Upsert'

标签 php postgresql

Upsert 是 PG 中的一个很棒的新东西(我们最近更新了数据库以使用它),现在我们正在尝试用 PHP 编写 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 中创建可以那样工作的适配器?我们知道应该更新哪一行的列名,所以应该可以构造ON CONFLICT ... DO UPDATE语句。我想更新任何冲突,就像

try {
 ...insert
} catch (Exception $e) {
 ...update
}

我们现在正在使用。

谢谢。

最佳答案

你想要实现 upsert 的方式,比如捕获 \Exception 意味着 «如果插入不管什么原因都不起作用,我会尝试更新。»承认这是真正缺乏对域的控制。例如,您可能希望在与主键冲突时更新行,但在与同一表中的唯一字段冲突时拒绝行。

冲突的原因属于模型,这些是明确实现为约束的业务规则。只有模型层知道为什么它会拒绝插入并改为更新行。因此,无论域定义如何,它都不能是您可以在所有表​​上调用的通用 upsert 命令。

这意味着这是 ModelTable 实例,它知道为什么记录会与现有数据冲突,就像它知道表结构一样(正如我从您的示例中猜测的那样)。

关于php - 如何以编程方式在 postgres 中使用 php 'Upsert',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42342907/

相关文章:

php - MYSQL错误结果输出

sql - 插入多行时重复项会发生什么情况?

java - 如何在 spring-boot 和 postgresql 中使用 postgis 类型地理?

php - 无法修改标题信息 session Cookie创建吗?

javascript - 联系表 7 带自动填充字段的条件字段

php - 来自mysql数据库的javascript变量

php - 取消设置类以清除内存

python - 为什么 SQLAlchemy 不创建串行列?

postgresql - postgres 中的 GROUP BY 列和子句

sql - postgreSQL 解释分析函数