“如果表存在则更新”在一个声明中 - 如何?

时间:2012-12-18 10:47:01

标签: sql postgresql postgresql-9.2

我的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”条件之前进行的(它是我们想要在连接中使用的相同表格。)。

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

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

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

但也许在一个声明中有某种简单而优雅的方式来做到这一点? :)

DBMS:PostgreSQL 9.2

1 个答案:

答案 0 :(得分: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的视图(如果它存在)和一个空表(如果它不存在)。