
postgresql 对双引号内的标识符严格区分大小写,若表或列名在建表时未用双引号定义,则实际存储为小写;查询时若双引号内拼写与数据库中真实名称不一致(如大小写偏差),将报“column does not exist”错误。
postgresql 对双引号内的标识符严格区分大小写,若表或列名在建表时未用双引号定义,则实际存储为小写;查询时若双引号内拼写与数据库中真实名称不一致(如大小写偏差),将报“column does not exist”错误。
在 PostgreSQL 中,双引号(")不是用于“保留大小写”的通用开关,而是显式启用大小写敏感标识符匹配的语法机制。其行为遵循以下核心规则:
✅ 建表时是否使用双引号,决定了元数据中存储的名称形态:
-
CREATE TABLE exploration_table (wlbncs TEXT);→ 表名和列名均以小写存入系统目录(pg_class/pg_attribute); -
CREATE TABLE "exploration_Table" ("wlbNCS" TEXT);→ 表名和列名按双引号内字面量精确存储(含大小写、下划线等)。
⚠️ 查询时双引号内容必须与系统目录中记录的名称 100% 一致(逐字符匹配):
您示例中的错误:
SELECT "exploration_Table"."wlbNCS" FROM "exploration_Table";
报错 column exploration_Table.wlbNCS does not exist,说明:
→ 实际数据库中该列名为 "wlbncs"(全小写),而非 "wlbNCS";
→ 或表名实为 "exploration_table",而非 "exploration_Table"。
? 验证真实名称的推荐方法(在 psql 或任何客户端执行):
-- 查看所有带引号的表名(含大小写) SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' AND table_name ~ '[A-Z_]'; -- 查看指定表的精确列名(注意:结果列名即为 pg_attribute.attname 值) SELECT column_name FROM information_schema.columns WHERE table_name = 'exploration_table' -- 这里用小写查(因建表未加引号) AND table_schema = 'public' ORDER BY ordinal_position;
更可靠的方式是直接查系统表(区分大小写):
SELECT attname AS column_name FROM pg_attribute JOIN pg_class ON pg_attribute.attrelid = pg_class.oid WHERE pg_class.relname = 'exploration_table' -- 不加引号 → 匹配小写存储名 AND attnum > 0 AND NOT attisdropped;
? 正确修复步骤:
-
确认建表 DDL:执行
\d "exploration_Table"(psql 中)或查pg_tables+pg_columns获取真实名称; -
统一使用小写无引号(推荐):只要建表时未用双引号,所有查询均可省略双引号,PostgreSQL 自动转为小写匹配:
SELECT exploration_table.wlbncs, well_top.lsustrat FROM exploration_table, well_top WHERE well_top.lsustrat = exploration_table.wlbformationid;
-
若必须保留大小写(如对接遗留命名规范):确保建表与查询完全一致:
-- 建表时即用双引号定义(一次设定,长期遵守) CREATE TABLE "Exploration_Table" ("WlbNCS" TEXT, "WlbFormationID" INT); -- 查询时严格镜像 SELECT "Exploration_Table"."WlbNCS" FROM "Exploration_Table";
❌ 重要澄清:PostgreSQL 不支持反引号(`)
答案中提到的“使用 back ticks 替代 double quotes”是常见误解——MySQL 用反引号,PostgreSQL 仅识别双引号作为标识符分隔符。在 PostgreSQL 中写 `exploration_Table` 将直接报语法错误。
? 最佳实践建议:
- ✅ 默认采用小写+下划线命名(
exploration_table,wlb_ncs),全程无需双引号,兼容性高、可读性强; - ✅ 在 Java JDBC 中,避免动态拼接双引号——改用
PreparedStatement参数化,表/列名通过白名单校验后安全注入; - ✅ 使用
DatabaseMetaData获取真实大小写名称(Java 端):DatabaseMetaData meta = conn.getMetaData(); try (ResultSet rs = meta.getColumns(null, null, "exploration_table", "%")) { while (rs.next()) { System.out.println("Actual column name: " + rs.getString("COLUMN_NAME")); // 返回真实存储名 } }
总结:错误根源不在双引号本身,而在于查询时双引号内的名称与数据库元数据中注册的名称不一致。解决关键在于“查准再写准”,而非替换符号。坚持小写无引号惯例,可从根本上规避此类问题。









