发生冲突时执行更新/不执行任何操作功能将在PostgreSQL9.5中提供。创建服务器和外部表将在PostgreSQL9.2版本中提供。
当我对FOREIGN表使用ON CONFLICT DO UPDATE时,它不起作用,但当我对普通表运行相同的查询时,它起作用。查询如下所示。
//对于普通表
INSERT INTO app
(app_id,app_name,app_date)
SELECT
p.app_id,
p.app_name,
p.app_date FROM app p
WHERE p.app_id=2422
ON CONFLICT (app_id) DO
UPDATE SET app_date = excluded.app_date ;
O/P:查询返回成功:影响一行,执行时间为5毫秒。
//对于外表概念
// foreign_app 是外表,app 是普通表
INSERT INTO foreign_app
(app_id,app_name,app_date)
SELECT
p.app_id,
p.app_name,
p.app_date FROM app p
WHERE p.app_id=2422
ON CONFLICT (app_id) DO
UPDATE SET app_date = excluded.app_date ;
O/P:错误:没有与ON CONFLICT规范匹配的唯一约束或排除约束
有人能解释为什么会发生这种情况吗?
2条答案
按热度按时间shyt4zoc1#
对外部表没有约束,因为PostgreSQL不能强制外部服务器上的数据完整性-这是由外部服务器上定义的约束来完成的。
为了达到你想要的目的,你必须坚持使用“传统”的方法(例如这个代码样本)。
iyzzxitl2#
我知道这是一个老问题,但在某些情况下,有一种方法可以使用ROW_NUMBER OVER(PARTION)来完成它。在我的例子中,我的第一个尝试是ON CONFLICT... DO UPDATE,但这不适用于外部表(如上所述;我的问题非常具体,因为我有一个外来表(f_zips),需要用尽可能好的邮政编码信息填充。我还有一个本地表 postcodes,其中包含非常好的数据,还有另一个本地表 zips,其中包含质量较低但更多的邮政编码信息。对于 postcodes 中的每一条记录,在 zips 中有对应的记录,但是邮政编码可能不匹配。2我希望 f_zips 保存最佳数据。
我用一个并集来解决这个问题,用 ind = 0 作为记录来自较好数据集的指示符,ind = 1 表示数据质量较差,然后我在一个分区上使用 row_number() 来得到答案(其中 get_valid_zip5() 是一个本地函数,返回5位数的邮政编码或空值):
我没有运行任何性能测试,但对我来说,这是在cron中运行的,不会直接影响用户。
验证超过900,000条记录(为简洁起见,省略SQL格式):