Oracle SQL执行插入语句报ORA-00984列不允许在此处如何处理?
ORA-00984 列在此处不允许 报错排查与解决
报错核心逻辑
Oracle对INSERT语句的语法约束是:列名只能出现在INSERT INTO 表名(列名清单)的括号范围内,VALUES子句的括号内必须是和列顺序对应的具体值(常量、绑定变量、无表列引用的计算表达式)。一旦Oracle把取值位的内容识别成了表的列名,就会抛出ORA-00984,提示列在此处不允许。
当前SQL的直接触发原因
对照给出的sales_order表结构和插入语句,报错的核心问题出在两个日期值的书写方式上:
- 原SQL中写的
12-jun-2014、20-jul-2014没有用单引号包裹,Oracle会把这类不带引号的字符序列识别为列标识符,甚至会把连字符解析成减法运算符,把整段内容当成“12 减去 名为jun的列值 减去 2014”的计算表达式 - 这种写法完全命中报错触发条件:取值位出现了不允许的列引用,自然抛出“列在此处不允许”的错误
同类问题通用排查清单
遇到相同报错可以按以下顺序逐行核对:
- 检查所有字符串、日期类型的字面量,是否用单引号正确包裹,避免被Oracle误识别为列名
- 核对INSERT语句结构:列名仅出现在表名后的列清单括号内,
VALUES后的括号内仅放对应位置的取值,不能混入列名 - 检查是否存在错位书写:比如把列名漏写在列清单中,反而错放到了取值位
可直接执行的修正后SQL
为了避免受会话NLS_DATE_FORMAT参数的干扰,推荐使用ANSI标准日期字面量处理日期值,修改后的语句如下:
insert into sales_order ( orderno , clientno , orderdate , delyaddr , salesmanno , delytype , billyn , delydate , orderstatus) values ( 'O19001', 'C00001', DATE '2014-06-12', 'Nadiad', 'S00001', 'F', 'N', DATE '2014-07-20', 'In Process' );
如果需要保留原日期的书写格式,也可以通过TO_DATE函数做显式转换,避免会话语言、格式参数影响解析结果:
-- 替换对应日期字段的写法即可 TO_DATE('12-jun-2014', 'dd-mon-yyyy', 'nls_date_language=american')
内容的提问来源于stack exchange,提问作者Krunal Akbari
相关产品推荐
相关产品推荐

