↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

百科 / SQL 状态码 / Class 21 基数违反

21000 cardinality_violation

基数冲突

ERROR 已实测 详解 实测通过

类别
Class 21 基数违反
严重等级
ERROR
条件名
cardinality_violation
宏名称
ERRCODE_CARDINALITY_VIOLATION
最早已知存在
7.4
状态
有效

手册收录:8.1、8.2、8.3、8.4、9.0、9.1、9.2、9.3、9.4、9.5、9.6、10、11、12、13、14、15、16、17、18、19、20。此处仅表示同版本手册收录,运行证据仍以原核验构建为准。

版本覆盖

版本条依据已采样构建显示;灰色版本可能尚未采样,悬停可查看。手册链接随版本选择,源码和运行证据保持原核验构建。

21000 — 基数冲突

速览 {#at-a-glance}

21000 表示操作得到的行数不符合基数契约。最常见的是标量子查询返回多行;它与 23505 不同,不要求存在唯一索引冲突。

含义 {#meaning}

把标量子查询当作表达式时,最多只能返回一行;执行器看到第二行就报告 21000,零行则产生 NULL。同一错误也用于命令级基数冲突:ON CONFLICT DO UPDATE 的多个候选行可能再次命中同一目标行,MERGE 的多个源行也可能匹配同一目标行;这些路径有各自的报文和提示。

诊断 {#diagnosis}

先保存 sqlstate、message_primary、hint 和语句上下文。根据业务键增加确定性谓词,或在确实要把多行合成一个值时使用聚合;不要随意加 LIMIT 1,否则可能静默选择任意行。对 ON CONFLICT,按仲裁索引或唯一键去重候选源行;对 MERGE,保证源到目标的匹配对每个目标至多一行。应检查实际源行和键映射,不能把它泛化成普通重复键错误。

处理 {#response}

显式事务中先回滚失败事务,再执行修正后的完整操作。ON CONFLICT 或 MERGE 的多行来源必须先确定基数;原样重放同一批数据仍会重复触发确定性的冲突。自动提交下本案例错误后连接仍为 IDLE,这不能替代外层事务或 PL/pgSQL 处理器的边界。

实测诊断 {#messages}

18.6 (Homebrew) / latest:SQLSTATE 21000;primary more than one row returned by a subquery used as an expression;status_after_error IDLE。 10.21 (Debian 10.21-1.pgdg90+1) / pg10:SQLSTATE 21000;primary more than one row returned by a subquery used as an expression;status_after_error IDLE。

代表案例 {#case}

运行器从 verify/cases/21000/snippets.json(SHA-256 6d820e94518ffca97f407956fdc2df104d47b14263d3117ff59dbc4409774dc2)读取下列片段,并为临时 schema 替换表名;完整 setup、断言与清理见 案例导出。

-- create
CREATE TABLE source_rows(id integer PRIMARY KEY);
-- seed
INSERT INTO source_rows VALUES (1), (2);
-- trigger
SELECT (SELECT id FROM source_rows ORDER BY id) AS only_id;
-- valid
SELECT (SELECT id FROM source_rows WHERE id = 1) AS only_id;

本案例对应的 SQLSTATE、诊断、事务状态和修复断言均来自上述共享 registry;结构化证据 · 案例导出。

作者证据 ID:identity, scalar-subquery, dml-conflict, runtime。选定运行记录:runtime.21000-batch1-latest-20260909.latest, runtime.21000-batch1-pg10-20260909.pg10。

版本与边界 {#versions}

锁定目录在 7.4 已观察到该条件,并在列出的 9.0–18.6 正式快照中均存在。固定源码证据确认 18.6 的标量子查询、ON CONFLICT 和 MERGE 路径;选定运行只覆盖 18.6 与 10.21 的标量子查询。

相关 {#related}

对比 23505 唯一约束冲突、23503 外键冲突 和 23000 完整性约束总类。

来源 {#sources}

  • src.errcodes.18.6 (SHA-256 6e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba)
  • src.calls.REL_18_6 (SHA-256 9ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf)
  • src.nodeSubplan.18.6 (SHA-256 c356a9812691f875974c1f476efa987015ba19e70a4be833a43b692f3554dc47)
  • src.nodeModifyTable.18.6 (SHA-256 0fc3cb180b3443f216142954e43d8ed5f84713d75094ce8cd2785ad8f604bd68)
  • doc.syntax.18.6 (SHA-256 449b0c500fccca068d0f8a1db2a5ebb5430eb83e33f12c6cb310a01a7437b635) · 官方文档

来源

证据

断言

每条断言都写明了是怎么核实的,以及它不覆盖什么。这一层是核验时留下的原始英文记录,照原样呈现,未经翻译。

运行记录

目标服务器版本结果覆盖案例
latest 18.6 (Homebrew) passed 案例:scalar_subquery_cardinality
pg10 10.21 (Debian 10.21-1.pgdg90+1) passed 案例:scalar_subquery_cardinality

报文模板

源码里的格式串,不是某一次运行的输出。%s 之类是占位符,实际报文会填入对象名与取值。适用范围一栏是核验时留下的原始英文记录,未经翻译。

主消息 more than one row returned by a subquery used as an expression

来源: 来源:src/backend/executor/nodeSubplan.c @ REL_18_6

适用范围:This is the scalar-subquery template; other 21000 paths have different templates.

主消息 %s command cannot affect row a second time
HINT Ensure that no rows proposed for insertion within the same command have duplicate constrained values. / Ensure that not more than one source row matches any one target row.

来源: 来源:src/backend/executor/nodeModifyTable.c @ REL_18_6

适用范围:The %s substitution is ON CONFLICT DO UPDATE or MERGE; the hint branch is command-specific.

可复现案例

在一次性实例上执行过的场景。其中 1 个附有可执行 SQL,正文相应小节里给出。

scalar_subquery_cardinality PG 10 / 18 有 SQL

前置条件

  • A disposable table contains two source rows
  • The scalar subquery is expected to return at most one row

触发

Use a two-row subquery in a scalar expression.

断言

  • SQLSTATE is 21000
  • The connection remains usable after the autocommit error
  • A one-row predicate succeeds afterward

处置

Make the scalar relation one row by predicate, aggregation, or an explicit application rule; do not add LIMIT without defining which row is correct.

清理

Drop the case schema with an owner connection.

同类 SQL 状态码

状态码 条件名 宏名称 严重等级 版本
Class 21 基数违反 Cardinality Violation 1 个 ↗
21000 cardinality_violation ERRCODE_CARDINALITY_VIOLATION ERROR 7.4 起已知
结果行数违反基数契约,如标量子查询返回多行。 有效