获取 PostgreSQL 中受 INSERT 或 UPDATE 影响的记录数
Posted
技术标签:
【中文标题】获取 PostgreSQL 中受 INSERT 或 UPDATE 影响的记录数【英文标题】:Get count of records affected by INSERT or UPDATE in PostgreSQL 【发布时间】:2011-05-01 14:49:09 【问题描述】:我的 PostgreSQL 8/9 数据库驱动程序在执行 INSERT
或 UPDATE
时不返回受影响的记录数。
PostgreSQL 提供了非标准语法“RETURNING”,这似乎是一个很好的解决方法。但是语法可能是什么?该示例返回记录的 ID,但我需要计数。
插入分销商(did、dname)值(默认值、'XYZ 小部件') 返回确实;
【问题讨论】:
我知道这听起来没什么帮助,但您必须为您当前的驱动程序找到更好的驱动程序或更新(OMG Ponies 发布的解决方案仅适用于 PL/pgSQL 代码)。 mysql 自动输出匹配的行和更新受影响的行,可惜 psql 驱动程序不能这样做。 没试过这个.. 但INSERT INTO distributors (did, dname) VALUES (DEFAULT, 'XYZ Widgets') RETURNING 1;
有效吗?
我尝试使用最新的 PostgreSQL 和 JDBC 驱动程序。成功插入似乎返回 1。没试过更新。
【参考方案1】:
我知道这个问题太难了,我的解决方案可能过于复杂,但这是我最喜欢的解决方案!
无论如何,我必须做同样的事情并让它像这样工作:
-- Get count from INSERT
WITH rows AS (
INSERT INTO distributors
(did, dname)
VALUES
(DEFAULT, 'XYZ Widgets'),
(DEFAULT, 'ABC Widgets')
RETURNING 1
)
SELECT count(*) FROM rows;
-- Get count from UPDATE
WITH rows AS (
UPDATE distributors
SET dname = 'JKL Widgets'
WHERE did <= 10
RETURNING 1
)
SELECT count(*) FROM rows;
这些天里,我真的不得不为 PostgreSQL 的 WITH 子句写一首爱情十四行诗……
【讨论】:
如何将计数分配给变量并引发通知?? @Udhaya 分配:SELECT ... INTO var FROM ...;
,提出通知:RAISE NOTICE '%', var;
。
但是如果你更新了 0 行,SELECT count(*) FROM rows;
不会返回 0。它不会返回任何记录。这是个问题。
我不同意“我的解决方案可能过于复杂”,这太棒了。
@mercurial 如果你读完那首爱情十四行诗,我很想读。【参考方案2】:
我同意 Milen,你的司机应该为你做这件事。您使用什么驱动程序以及使用什么语言?但是如果你使用的是plpgsql,你可以使用GET DIAGNOSTICS my_var = ROW_COUNT;
http://www.postgresql.org/docs/current/static/plpgsql-statements.html
【讨论】:
这很幽默,因为这是@OMGPonies 在 2010 年给出的(现已删除和隐藏的)答案。【参考方案3】:您可以在更新后使用ROW_COUNT
或使用此代码插入:
insert into distributors (did, dname) values (DEFAULT, 'XYZ Widgets');
get diagnostics v_cnt = row_count;
【讨论】:
【参考方案4】:从您的问题中不清楚您如何称呼该声明。假设您使用的是 JDBC 之类的东西,您可能会将其称为查询而不是更新。来自 JDBC 的executeQuery
:
执行给定的 SQL 语句,返回单个 ResultSet 对象。
因此,这适用于执行返回某些查询结果的语句,例如SELECT
或INSERT ... RETURNING
。如果您正在更新数据库,然后想知道有多少元组受到影响,您需要使用executeUpdate
,它会返回:
任一 (1) SQL 数据操作语言 (DML) 的行数 语句或 (2) 0 用于不返回任何内容的 SQL 语句
【讨论】:
【参考方案5】:您可以将查询包装在事务中,它应该在您ROLLBACK
或COMMIT
之前向您显示计数。示例:
BEGIN TRANSACTION;
INSERT .... ;
ROLLBACK TRANSACTION;
如果您运行上面的前 2 行,它应该会给您计数。然后,如果您发现受影响的行数不是您的预期,您可以ROLLBACK
(撤消)插入。如果您对 INSERT
的正确性感到满意,那么您可以运行相同的操作,但将第 3 行替换为 COMMIT TRANSACTION;
。
重要提示:在您运行任何BEGIN TRANSACTION;
后,您必须在ROLLBACK;
或COMMIT;
事务中,否则事务将创建一个可能会减慢速度的锁如果您在生产环境中运行,则会关闭甚至削弱整个系统。
【讨论】:
以上是关于获取 PostgreSQL 中受 INSERT 或 UPDATE 影响的记录数的主要内容,如果未能解决你的问题,请参考以下文章
postgresql----数据库表约束----UNIQUE
如何在 flask_sqlalchemy 中使用 PostgreSQL 的“INSERT...ON CONFLICT”(UPSERT)功能?