百科 / 错误代码 / Class 42 语法错误或访问规则冲突
42P04 duplicate_database
重复数据库
ERROR 源码确认 详解 未实测
- 条件名
duplicate_database- 宏名称
ERRCODE_DUPLICATE_DATABASE- 启用版本
- 7.4
- 状态
- 活跃
版本覆盖
速览
42P04(duplicate_database)表示数据库管理路径发现集群中已有同名数据库。这是集群级名称检查,不是当前库内的关系冲突;CREATE 和 RENAME 的外围检查也不同。
含义
createdb 会用 get_database_oid(dbname, true) 检查目标名称,冲突时报告 ERROR database "%s" already exists。RenameDatabase 在查找旧数据库、检查所有权和 CREATEDB 权限之后,对 newname 做同样检查。因此 %s 在 CREATE 中是请求的数据库名,在 RENAME 中是新名称。
utility 分发器在进入 createdb 前调用 PreventInTransactionBlock(isTopLevel, "CREATE DATABASE")。所以在显式事务中执行 CREATE DATABASE 是另一种事务块错误,不能据此声称发出了 42P04;RENAME 则有独立的旧名、所有权、权限和新名检查。
诊断
确认目标集群和准确名称,检查 pg_database、标识符折叠和迁移竞争。CREATE 另查目标名称、模板和所有者前提;RENAME 同时查旧名、新名、所有权和 CREATEDB。旧数据库不存在或权限不足不应误判为 42P04。
处理
已有库就是目标时让编排幂等并检查它;否则选择未占用名称。CREATE DATABASE 要在顶层、显式事务块之外执行。RENAME 只有在确认旧库、所有权、CREATEDB、活动会话、依赖和集群身份后才选择可用新名。如果 RENAME 在显式事务中报错,下一条命令前应执行 ROLLBACK;若必须保留外层事务,则回滚到改名前建立的保存点。删除或改名不是所有 42P04 的通用修复。
消息变体
选定路径均为 ERROR database "%s" already exists:createdb 使用请求名称,RenameDatabase 使用新名称。utility 中的 PreventInTransactionBlock 证明 CREATE DATABASE 有独立事务限制,不是另一条 42P04 报文。
报文模板
源码里的格式串,不是某一次运行的输出。%s 之类是占位符,实际报文会填入对象名与取值。适用范围一栏是核验时留下的原始英文记录,未经翻译。
database "%s" already exists
来源:src/backend/commands/dbcommands.c(lines 1393-1395) @ REL_18_6
适用范围:Placeholders remain dynamic source fields; no concrete runtime value is claimed.
database "%s" already exists
来源:src/backend/commands/dbcommands.c(lines 1949-1951) @ REL_18_6
适用范围:Placeholders remain dynamic source fields; no concrete runtime value is claimed.
版本
目录范围从 7.4 到 18.6、19beta3,不是精确的功能引入判断。选定的是 18.6 固定 CREATE、RENAME 和分发器事务检查路径,未运行数据库。
来源
- 上游源码 src/backend/commands/dbcommands.c 第 1393–1395 行
- 上游源码 src/backend/commands/dbcommands.c 第 1949–1951 行
- 上游源码 src/backend/tcop/utility.c 第 769–773 行
- 上游源码 src/backend/utils/errcodes.txt 第 379 行
- 核验材料 raw/calls/REL_18_6.jsonl
证据
断言
每条断言都写明了是怎么核实的,以及它不覆盖什么。这一层是核验时留下的原始英文记录,照原样呈现,未经翻译。
-
42P04 is the duplicate_database condition in Class 42.
-
createdb checks the requested database name and RenameDatabase checks newname after old-database ownership and CREATEDB checks; both report ERROR `database "%s" already exists`. The utility dispatcher separately calls PreventInTransactionBlock for CREATE DATABASE before createdb, so an explicit transaction-block failure is not 42P04.
-
From 7.4 through 18.6 and 19beta3; this catalogue range is not a precise introduction claim. The selected CREATE, RENAME, and dispatcher guards are fixed 18.6 source paths and no runtime case was run.
同类错误代码
Class 42 语法错误或访问规则冲突 下的其他成员。
42000syntax_error_or_access_rule_violation42501insufficient_privilege42601syntax_error42602invalid_name42611invalid_column_definition42622name_too_long42701duplicate_column42702ambiguous_column42703undefined_column42704undefined_object42710duplicate_object42712duplicate_alias42723duplicate_function42725ambiguous_function42803grouping_error42804datatype_mismatch42809wrong_object_type42830invalid_foreign_key42846cannot_coerce42883undefined_function428C9generated_always42939reserved_name42P01undefined_table42P02undefined_parameter42P03duplicate_cursor42P05duplicate_prepared_statement42P06duplicate_schema42P07duplicate_table42P08ambiguous_parameter42P09ambiguous_alias42P10invalid_column_reference42P11invalid_cursor_definition42P12invalid_database_definition42P13invalid_function_definition42P14invalid_prepared_statement_definition42P15invalid_schema_definition42P16invalid_table_definition42P17invalid_object_definition42P18indeterminate_datatype42P19invalid_recursion42P20windowing_error42P21collation_mismatch42P22indeterminate_collation