已多次询问here和here,但在我的情况下,没有一个答案是合适的,因为我不想在PL / PgSQL函数中执行我的更新语句并使用{ {1}}。
我必须在原始SQL中执行此操作。
例如,在MS SQL SERVER中,我们有@@ ROWCOUNT,可以像下面这样使用:
GET DIAGNOSTICS integer_var = ROW_COUNT
在数据库的一次往返中,我知道更新是否成功,并获得计算出的值。
可以用什么代替'@@ ROWCOUNT'? 有人可以确认此时这实际上是不可能的吗?
提前致谢。
编辑1 :我确认我需要使用原始SQL(我在原始描述中写了“raw plpgsql”)。
为了使我的问题更清楚,请考虑更新语句只影响一行并考虑乐观并发:
客户首先发表了UPDATE <target_table>
SET Proprerty0 = Value0
WHERE <predicate>;
SELECT <computed_value_columns>
FROM <target>
WHERE @@ROWCOUNT > 0;
声明。
他构建UPDATE并知道哪些数据库计算列将包含在SELECT子句中。除其他外,谓词包括每次更新行时计算的时间戳。
所以,如果我们返回1行,那么一切都OK。如果没有返回行,那么我们知道先前有更新,并且客户端可能需要在再次尝试更新子句之前刷新数据。这就是为什么我们需要知道在返回计算列之前受update语句影响的行数。如果更新失败,则不应返回任何行。
答案 0 :(得分:12)
您想要的内容目前无法以您描述的形式出现,但我认为您可以使用UPDATE ... RETURNING
执行所需操作。请参阅UPDATE ... RETURNING
in the manual。
UPDATE <target_table>
SET Proprerty0 = Value0
WHERE <predicate>
RETURNING Property0;
很难确定,因为你提供的例子是如此抽象,以至于毫无意义。
您还可以使用wCTE,它允许更复杂的情况:
WITH updated_rows AS (
UPDATE <target_table>
SET Proprerty0 = Value0
WHERE <predicate>
RETURNING row_id, Property0
)
SELECT row_id, some_computed_value_from_property
FROM updated_rows;
请参阅common table expressions (WITH
queries)和depesz's article on wCTEs。
更新根据问题中的一些附加细节,这是使用UPDATE ... RETURNING
的演示:
CREATE TABLE upret_demo(
id serial primary key,
somecol text not null,
last_updated timestamptz
);
INSERT INTO upret_demo (somecol, last_updated) VALUES ('blah',current_timestamp);
UPDATE upret_demo
SET
somecol = 'newvalue',
last_updated = current_timestamp
WHERE last_updated = '2012-12-03 19:36:15.045159+08' -- Change to your timestamp
RETURNING
somecol || '_computed' AS a,
'totally_new_computed_column' AS b;
第一次运行时的输出:
a | b
-------------------+-----------------------------
newvalue_computed | totally_new_computed_column
(1 row)
再次运行时,它将无效并且不返回任何行。
如果要在结果集中进行更复杂的计算,可以使用wCTE,这样就可以加入更新结果并执行其他复杂的操作。
WITH upd_row AS (
UPDATE upret_demo SET
somecol = 'newvalue',
last_updated = current_timestamp
WHERE last_updated = '2012-12-03 19:36:15.045159+08'
RETURNING id, somecol, last_updated
)
SELECT
'row_'||id||'_'||somecol||', updated '||last_updated AS calc1,
repeat('x',4) AS calc2
FROM upd_row;
换句话说:使用UPDATE ... RETURNING
直接生成计算的行,或者使用可写的CTE来处理更复杂的情况。
答案 1 :(得分:0)
一般来说,这个问题的答案取决于所使用的驱动程序的类型。
PQcmdTuples() 函数执行需要的操作,如果应用程序使用 libpq。 libpq 之上的其他库需要在此函数之上有一些包装器。
对于 JDBC,Statement.executeUpdate() 方法似乎可以胜任。
ODBC 提供了用于类似目的的 SQLRowCount() 函数。