3

我对作为长事务的一部分的 SQL 语句有疑问。

UPDATE tab_1 LEFT JOIN tab_2 ON tab_1.id = tab_2.tab_1_id SET tab_1.something = 42 WHERE tab1.id = tab_2.tab_1_id;

只要数据库中存在 tab_1 和 tab_2 ,一切都很简单并且工作正常,这是显而易见的。;-)

问题是事务必须在 4 个不同的服务器上提交,并且 tab_2 是“动态”表,它可能存在于特定的 db / db 模式中,或者不......

如果 tab_2 不存在,数据库抛出异常并且整个事务没有提交。我想要的是继续(只需更新 0 行)!

我尝试过这样的事情:

UPDATE [all the same as above] WHERE tab1.id = tab_2.tab_1_id AND EXISTS (select 1 from pg_class where relname='tab_2');

...但它仍然是错误的,因为“异常检查”是在“where”条件之前进行的(它是我们要在 join 中使用的同一个表..)。

有没有办法用“纯” SQL 做到这一点?:)

类似于:LEFT JOIN tab_2 IF tab_2 EXISTS(如果不存在 - 什么也不做,返回 null 等?)

我知道在 pl/pgsql 过程中有一种方法可以做到这一点。第二种可能性是在语句之​​前创建表(如果不存在)。

但也许有某种简单而优雅的方法可以在一个语句中做到这一点?:)

数据库管理系统:PostgreSQL 9.2

4

1 回答 1

2

我不认为UPDATE即使表不存在也能成功的语句是简单而优雅的。我认为这很奇怪和令人困惑。

为什么不只包含一个检查该表是否存在的条件,并且只在它存在时才执行更新?会清楚很多。

另一种选择是创建一个指向tab_2它是否存在的视图,否则指向一个空表。如果您有很多这样的查询,并且您不想全部更改,这可能会有所帮助。

更新:这是条件的样子(必须在函数或BEGIN...END块内):

IF EXISTS (select 1 from pg_class where relname='tab_2') THEN 
   UPDATE...
END IF;

根据 Postgresql 的详细信息,如果它看到语句中不存在的UPDATE表(我不是 Postgresql 用户),它仍然可能会导致编译失败。在这种情况下,您需要创建一个指向它是否存在的视图,tab_2如果它不存在则创建一个空表。

于 2012-12-18T10:52:40.593 回答