首页 > 解决方案 > 更新时引用无效,那么,如何更新呢?

问题描述

在我的梦想中,UPDATE子句(对于hhschema表s)是这样的:

UPDATE s.hh
SET x = t.a, y=t.b
FROM func_ret_table('n',hh.ids) t(a, b)
WHERE hh.z IS NOT NULL

但是对于 PostgreSQL 来说是一个无效的参考......那么,如何在不重做所有软件的情况下进行更新?

该函数func_ret_table()只返回一行——因此在 WHERE 子句中不需要“加入”。


原始错误消息:

ERROR:  invalid reference to FROM-clause entry for table "li_raw_compact"
LINE 3: FROM wdosm.get_member_wds('n',li_raw_compact.n_ref_ids) t(os...
                                       ^
TIP:  There is an entry for table "li_raw_compact", but it cannot be referenced from this part of the query.

翻译成上面的例子:

ERROR:  invalid reference to FROM-clause entry for table "hh"
LINE 3: FROM func_ret_table('n',hh.ids) t(os...
                                  ^
TIP:  There is an entry for table "hh", but it cannot be referenced from this part of the query.

不优雅也不考虑解决方案

CREATE VIEW vw_ab_update AS 
  SELECT w.id, t.a, t.b 
  FROM s.hh, LATERAL func_ret_table('n',hh.ids) t(a, b) 
  WHERE hh.z IS NOT NULL
;
UPDATE s.hh
SET x = t.a, y=t.b
FROM vw_ab_update t
WHERE hh.id=t.id
;

在我的真实情况下,我需要一个复杂的 sql-view ......我正在使用,但作为解决方案是如此丑陋。

标签: postgresqlsql-update

解决方案


可以使用类似 ROW 的语法在单个赋值中更新多个列:

update t set
  (x, y) = (1, 2)

或者

update t set
  (x, y) = (select 1, 2)

等,请参阅语句的定义UPDATE

[ WITH [ RECURSIVE ] with_query [, ...] ]
UPDATE [ ONLY ] table_name [ * ] [ [ AS ] alias ]
    SET { column_name = { expression | DEFAULT } |
          ( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT } [, ...] ) |
          ( column_name [, ...] ) = ( sub-SELECT )
        } [, ...]
    [ FROM from_list ]
    [ WHERE condition | WHERE CURRENT OF cursor_name ]
    [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]

因此,您的查询可以重写为:

UPDATE s.hh
SET (x, y) = (SELECT a, b FROM func_ret_table('n',hh.ids) t(a, b))
WHERE hh.z IS NOT NULL

注意:该( column_name [, ...] ) = ( sub-SELECT )语法仅在 ~2016 年与 PostgreSQL v9.5一起引入......它还不是很为人所知,但它是如此有用!


推荐阅读