达梦数据库表字段增加时报错[-2106]:无效的表或视图名,[-2116]:列[IS_REPEAT]已存在

ALTER TABLE "DM"."EMPLOYEE" add "IS_REPEAT" VARCHAR(255);

COMMENT ON COLUMN "DM"."EMPLOYEE"."IS_REPEAT" IS '是否重复,1、是,0、否';

报错:无效的表或视图名[EMPLOYEE]

已知我已经创建了employee表

CREATE TABLE employee

(

employee_id INTEGER,

employee_name VARCHAR2(20) NOT NULL,

hire_date DATE,

salary INTEGER,

department_id INTEGER NOT NULL

);

sql 复制代码
-- 创建employee表
CREATE TABLE employee
(
  employee_id INTEGER,
  employee_name VARCHAR2(20) NOT NULL,
  hire_date DATE,
  salary INTEGER,
  department_id INTEGER NOT NULL
);
-- 使用 CREATE TABLE 语句创建 department 表
CREATE TABLE department
(
  department_id INTEGER PRIMARY KEY,
  department_name VARCHAR(30) NOT NULL
);
-- 非空约束
ALTER TABLE employee MODIFY( hire_date not null);
-- 主键约束
ALTER TABLE employee ADD constraint pk_empid PRIMARY KEY(employee_id);
-- 外键约束
ALTER TABLE employee ADD constraint fk_dept FOREIGN KEY (department_id) REFERENCES department (department_id);

这个错误表明数据库无法找到名为 "EMPLOYEE" 的表。以下是可能的原因和解决方案:

错误原因分析

  1. 表名大小写问题
    • 达梦数据库默认是大小写敏感的
    • 您可能创建的是 employee 而非 EMPLOYEE
  1. 模式(用户)名问题
    • 表可能不在 DM 模式下
    • 您可能没有使用正确的模式名前缀
  1. 表不存在
    • 该表可能尚未创建或已被删除

解决方案

方案1:检查表名大小写

sql 复制代码
-- 查询当前用户下的所有表(不区分大小写)
SELECT table_name FROM all_tables WHERE owner = 'DM' AND UPPER(table_name) = 'EMPLOYEE';

-- 或者查询精确匹配
SELECT table_name FROM all_tables WHERE owner = 'DM' AND table_name = 'EMPLOYEE';

【检查过发现无误】

方案2:尝试不加引号的表名

sql 复制代码
ALTER TABLE DM.EMPLOYEE ADD IS_REPEAT VARCHAR(255);
COMMENT ON COLUMN DM.EMPLOYEE.IS_REPEAT IS '是否重复,1、是,0、否';

【尝试过发现依旧报错:无效的表或视图名[EMPLOYEE]】

方案3:确认正确的模式名

sql 复制代码
-- 查询所有模式下的EMPLOYEE表
SELECT owner, table_name FROM all_tables WHERE UPPER(table_name) = 'EMPLOYEE';

-- 如果表在其他模式下,使用正确的模式名
ALTER TABLE 实际模式名.EMPLOYEE ADD IS_REPEAT VARCHAR(255);

【我使用SELECT owner, table_name FROM all_tables WHERE UPPER(table_name) = 'EMPLOYEE';查询了之后发现EMPLOYEE的owner有三个,分别为RESOURCES,DMHR,SYSDBA,这说明表不在 DM 模式下,问题找出来了】

方案4:确认表是否存在

sql 复制代码
-- 在DM模式下创建表(如果不存在)
CREATE TABLE DM.EMPLOYEE (
    employee_id INTEGER,
    employee_name VARCHAR(20) NOT NULL,
    hire_date DATE,
    salary INTEGER,
    department_id INTEGER NOT NULL
);

【表确认存在】

问题排查

我的查询结果表明 EMPLOYEE 表确实不在 DM 模式下,而是存在于以下三个不同的模式(用户)中:

  1. RESOURCES
  2. DMHR
  3. SYSDBA

这意味着:

  1. 表不在 DM 模式下
    我之前尝试的 ALTER TABLE "DM"."EMPLOYEE" 操作失败是正常的,因为该模式下确实不存在这个表。
  2. 存在多个同名的 EMPLOYEE 表
    这三个模式中各自都有一个名为 EMPLOYEE 的表(可能是达梦的示例表或系统预置表)。

此时应该:

1. 确认要操作的是哪个模式下的表

sql 复制代码
-- 查看这三个表的结构是否相同(确认哪个是您需要的)
SELECT * FROM RESOURCES.EMPLOYEE WHERE ROWNUM <= 1;
SELECT * FROM DMHR.EMPLOYEE WHERE ROWNUM <= 1; 
SELECT * FROM SYSDBA.EMPLOYEE WHERE ROWNUM <= 1;

2. 选择正确的模式名前缀操作

sql 复制代码
-- 示例:修改DMHR模式下的EMPLOYEE表
ALTER TABLE DMHR.EMPLOYEE ADD IS_REPEAT VARCHAR(255);
COMMENT ON COLUMN DMHR.EMPLOYEE.IS_REPEAT IS '是否重复,1、是,0、否';

3. 如果您需要在 DM 模式下操作

sql 复制代码
-- 方案A:将其他模式的表复制到DM模式
CREATE TABLE DM.EMPLOYEE AS SELECT * FROM DMHR.EMPLOYEE;

-- 方案B:直接在DM模式下创建新表
CREATE TABLE DM.EMPLOYEE (
  employee_id INTEGER,
  employee_name VARCHAR(20),
  -- 其他列...
  department_id INTEGER
);

补充说明

  1. 达梦的默认示例表
    DMHR.EMPLOYEE 很可能是达梦自带的人力资源管理示例表,RESOURCES.EMPLOYEE 可能是资源管理示例表。
  2. 权限问题
    如果您没有这些模式的权限,需要联系DBA授权:
sql 复制代码
-- 授权示例(需SYSDBA执行)
GRANT SELECT, INSERT, UPDATE, DELETE ON DMHR.EMPLOYEE TO DM;
  1. 最佳实践

建议在您自己的模式(如DM)下创建和维护表,避免修改系统预置的示例表。

补充建议

  1. 在达梦数据库中,建议统一使用大写表名以避免大小写问题
  2. 执行DDL操作前,先用查询确认表是否存在
  3. 检查当前登录用户是否有操作该表的权限

如果以上方案都不能解决问题,可能是权限问题,您需要联系DBA确认:

sql 复制代码
-- 检查当前用户权限
SELECT * FROM session_roles;
SELECT * FROM user_tab_privs WHERE table_name = 'EMPLOYEE';

执行顺序反了又报错:

这次40行执行失败了,而第41行成功了。于是导致:

执行了COMMENT ON COLUMN "DM"."EMPLOYEE"."IS_REPEAT" IS '是否重复,1、是,0、否';

之后再执行ALTER TABLE "DM"."EMPLOYEE" add "IS_REPEAT" VARCHAR(255);,

出现报错[-2116]:列[IS_REPEAT]已存在

这个错误是因为执行的顺序反了,导致列还没创建就先添加了注释。以下是详细分析和解决方案:

错误原因

  1. 执行顺序错误
    • 您先执行了 COMMENT ON COLUMN(为列添加注释)
    • 然后才执行 ALTER TABLE...ADD(添加列)
    • 但此时列还不存在,所以报错列已存在(这个错误信息有些误导)
  1. 达梦数据库特性
    • 达梦在执行DDL时会检查元数据一致性
    • 当添加注释时系统已经记录了这个列名,导致后续真正添加列时冲突

正确顺序

sql 复制代码
-- 1. 先添加列
ALTER TABLE "DM"."EMPLOYEE" ADD "IS_REPEAT" VARCHAR(255);

-- 2. 再添加列注释
COMMENT ON COLUMN "DM"."EMPLOYEE"."IS_REPEAT" IS '是否重复,1、是,0、否';

如果已经报错怎么办

方案1:清除错误状态后重试

sql 复制代码
-- 先回滚当前事务
ROLLBACK;

-- 然后按正确顺序执行
ALTER TABLE "DM"."EMPLOYEE" ADD "IS_REPEAT" VARCHAR(255);
COMMENT ON COLUMN "DM"."EMPLOYEE"."IS_REPEAT" IS '是否重复,1、是,0、否';

【这个回滚我尝试之后发现不能清除已存在的列,故失败】

方案2:检查并删除残留元数据(需DBA权限)

sql 复制代码
-- 查询是否存在残留的列定义
SELECT * FROM ALL_TAB_COLUMNS 
WHERE OWNER = 'DM' 
AND TABLE_NAME = 'EMPLOYEE' 
AND COLUMN_NAME = 'IS_REPEAT';

-- 如果存在且确实不需要,可以强制删除(谨慎操作)
ALTER TABLE "DM"."EMPLOYEE" DROP COLUMN "IS_REPEAT";

【查询之后发现确实存在残留的列定义IS_REPEAT,于是进行了强制删除】

然后再次执行ALTER TABLE DM.EMPLOYEE add IS_REPEAT VARCHAR(255);

注意:

ALTER TABLE "DM"."EMPLOYEE" add "IS_REPEAT" VARCHAR(255);

ALTER TABLE DM.EMPLOYEE add IS_REPEAT VARCHAR(255);

均可,但是

ALTER TABLE DM.employee add IS_REPEAT VARCHAR(255);

不可以。

因为达梦数据库默认是大小写敏感的,我之前就是因为employee写成了小写导致的报错。

即对于创建表,即在大小写敏感的情况下,表名employee不加双引号,系统会自动转换成大写表名EMPLOYEE

补充建议

  1. 事务管理
sql 复制代码
BEGIN
  ALTER TABLE "DM"."EMPLOYEE" ADD "IS_REPEAT" VARCHAR(255);
  COMMENT ON COLUMN "DM"."EMPLOYEE"."IS_REPEAT" IS '是否重复,1、是,0、否';
  COMMIT;
EXCEPTION
  WHEN OTHERS THEN
    ROLLBACK;
    RAISE;
END;
  1. 验证列是否存在
ini 复制代码
-- 执行前先检查
SELECT COUNT(*) FROM ALL_TAB_COLUMNS 
WHERE OWNER = 'DM' 
AND TABLE_NAME = 'EMPLOYEE' 
AND COLUMN_NAME = 'IS_REPEAT';
  1. 达梦特有语法

达梦也支持合并操作:

sql 复制代码
ALTER TABLE "DM"."EMPLOYEE" 
ADD "IS_REPEAT" VARCHAR(255) 
COMMENT '是否重复,1、是,0、否';
相关推荐
程序人生5183 小时前
MongoDB 查询时区问题
数据库·mongodb
cookqq3 小时前
mongodb源代码分析createCollection命令由create.idl变成create_gen.cpp过程
数据库·算法·mongodb·nosql
Navicat中国4 小时前
Navicat 17.3 正式发布 | 现已支持达梦、金仓和 IvorySQL 数据库
数据库·数据库开发·达梦·数据可视化·navicat
Dajiaonew5 小时前
从零搭建Cloud Alibaba
java·数据库·分布式·微服务
李宥小哥5 小时前
SQL通用增删改查
数据库·sql
张晓~183399481216 小时前
如果通过源码技术实现矩阵系统分部门管理?
jvm·数据库·线性代数·算法·microsoft·矩阵·html5
黑客飓风6 小时前
MySQL配置性能优化赛
数据库·mysql·性能优化
JeffreyGu.6 小时前
【Oracle】Oracle 11g 中扩展表空间
数据库·oracle
盟接之桥7 小时前
盟接之桥说制造:差异化定位与效率竞争的双轮驱动
大数据·服务器·数据库·人工智能·制造
徐子童8 小时前
初识Redis---Redis的特性介绍
java·数据库·redis