java.sql.SQLSyntaxErrorException: ORA-00984: 列在此处不允许

本文记录了一次在使用MyBatis框架操作Oracle数据库时遇到的ORA-00984错误,并详细展示了错误堆栈跟踪及修改前后的SQL语句对比,最终解决了列在此处不允许的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Exception in thread "main" org.springframework.jdbc.BadSqlGrammarException:
### Error updating database.  Cause: java.sql.SQLSyntaxErrorException: ORA-00984: 列在此处不允许

### The error may involve com.atsig.uac.persistence.AccountMapper.addAccount-Inline
### The error occurred while setting parameters
### Cause: java.sql.SQLSyntaxErrorException: ORA-00984: 列在此处不允许

; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: ORA-00984: 列在此处不允许

    at org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:94)[FDDS]05-19 18:33:47[SqlSessionUtils.debug] Closing no transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6d999a]

    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
    at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:71)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:346)
    at $Proxy6.insert(Unknown Source)
    at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:231)
    at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:56)
    at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:38)
    at $Proxy7.addAccount(Unknown Source)
    at com.atsig.uac.service.AccountService.addAccount(AccountService.java:27)
    at com.atsig.uac.test.UACTest.main(UACTest.java:93)
Caused by: java.sql.SQLSyntaxErrorException: ORA-00984: 列在此处不允许

    at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:91)
    at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:112)
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:173)
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:455)
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:413)
    at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:1030)
    at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:194)
    at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:947)
    at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1222)
    at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3381)
    at oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:3482)
    at oracle.jdbc.driver.OraclePreparedStatementWrapper.execute(OraclePreparedStatementWrapper.java:1373)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.logicalcobwebs.proxool.ProxyStatement.invoke(ProxyStatement.java:100)
    at org.logicalcobwebs.proxool.ProxyStatement.intercept(ProxyStatement.java:57)
    at oracle.jdbc.OracleStatement$$EnhancerByProxool$$26166e92.execute(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:45)
    at $Proxy11.execute(Unknown Source)
    at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:22)
    at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:51)
    at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:29)
    at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:75)
    at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:43)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:118)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:107)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:338)
    ... 7 more


原因及

解决办法

 

 

<insert id="addAccount" parameterType="Account">
        insert into
        SYSTEM_ACCOUNT(ACCOUNT_NAME,ACCOUNT_PWD,ACCOUNT_DESC,ACCOUNT_TYPE,GROUP_ID)
        values(${accountName},${accountPwd},${accountDesc},${accountType},${funcSetId})
    </insert>


更改(解决)如下

 

<insert id="addAccount" parameterType="Account">
        insert into
         SYSTEM_ACCOUNT(ACCOUNT_NAME,ACCOUNT_PWD,ACCOUNT_DESC,ACCOUNT_TYPE,GROUP_ID)
        values('${accountName}','${accountPwd}','${accountDesc}','${accountType}',${funcSetId})
 </insert>

 


<think>好的,我现在需要处理用户遇到的数据库错误:Error updating database. Cause: java.sql.SQLSyntaxErrorException: ORA-01790: expression must have same datatype as corresponding expression。首先,我得理解这个错误的原因。 ORA-01790错误通常发生在SQL语句中,当两个需要相同数据类型的表达式类型匹配时。比如在UNION、INTERSECT、MINUS操作,或者IN子句、CASE WHEN等需要比较或合并的情况下,如果对应的数据类型一致,就会触发这个错误。 用户提到错误可能存在于URL,这可能是指数据库连接URL,但更可能的是在SQL语句中的某个部分。接下来,我需要分析可能的原因和解决方法。 首先,检查SQL语句中是否有UNION、INTERSECT、MINUS等集合操作。这些操作要求每个SELECT子句对应的数据类型必须一致。例如,第一个SELECT的第二是VARCHAR2,第二个SELECT的第二是NUMBER,就会报错。需要确认每个对应的数据类型是否匹配。 其次,检查IN子句中的数据类型是否一致。比如WHERE column IN (1, '2', 3),这里混合了数字和字符串,会导致类型匹配。应确保IN表中的所有值类型与的类型一致。 另外,CASE WHEN语句中的各个分支返回的数据类型是否一致?每个WHEN和ELSE的返回值必须类型相同,否则也会出错。例如,CASE WHEN条件 THEN 0 ELSE 'N/A' END,这里一个是数字,一个是字符串,会引发错误。 还有可能是在JOIN操作中,连接的数据类型匹配。比如使用ON table1.id = table2.id,但一个是VARCHAR2,另一个是NUMBER,需要显式转换或修改表结构。 此外,INSERT或UPDATE语句中的和值类型匹配。例如,将字符串插入数字,或者反之。需要检查VALUES部分或SET部分的数据类型是否与表结构一致。 解决方法包括:使用CAST或TO_CHAR、TO_NUMBER等函数显式转换数据类型;修改表结构使相关类型一致;检查应用层代码,确保传入参数类型正确;在UNION等操作中确保每个SELECT的类型匹配。 可能还需要查看具体的SQL语句和表结构,比如用户是否在某个查询中混合了同的类型,或者在动态生成SQL时参数类型正确。建议用户检查报错位置附近的SQL,确认是否有上述问题,逐步排除可能的原因。</think>### 错误分析:`ORA-01790: expression must have same datatype as corresponding expression` 这个错误通常发生在 **SQL 语句中需要数据类型一致的表达式,但实际数据类型匹配** 的场景。以下是常见原因和解决方法: --- #### 1. **集合操作(UNION/INTERSECT/MINUS)数据类型匹配** - **问题描述** 当使用 `UNION`、`INTERSECT`、`MINUS` 等集合操作时,**每个子查询的对应必须具有相同的数据类型**。 例如: ```sql SELECT id, name FROM table1 -- name 是 VARCHAR2 类型 UNION SELECT id, age FROM table2; -- age 是 NUMBER 类型 ``` 此处第二个查询的 `age`(NUMBER)与第一个查询的 `name`(VARCHAR2)类型匹配。 - **解决方法** 使用 `CAST` 或 `TO_CHAR`、`TO_NUMBER` 等函数显式转换数据类型: ```sql SELECT id, name FROM table1 UNION SELECT id, TO_CHAR(age) FROM table2; -- 将 age 转为 VARCHAR2 ``` --- #### 2. **IN 子句中的数据类型一致** - **问题描述** `IN` 子句中的值必须与目标的数据类型一致。例如: ```sql SELECT * FROM employees WHERE department_id IN (10, '20', 30); -- '20' 是字符串,其他是数字 ``` 混合了 `NUMBER` 和 `VARCHAR2` 类型会导致错误。 - **解决方法** 统一数据类型: ```sql SELECT * FROM employees WHERE department_id IN (10, 20, 30); -- 全部改为 NUMBER ``` --- #### 3. **CASE WHEN 分支数据类型一致** - **问题描述** `CASE WHEN` 的每个分支返回值必须类型一致: ```sql SELECT CASE WHEN status = 1 THEN 'Active' -- VARCHAR2 WHEN status = 0 THEN 0 -- NUMBER END FROM users; ``` 此处分支返回了 `VARCHAR2` 和 `NUMBER` 两种类型。 - **解决方法** 统一返回值类型: ```sql SELECT CASE WHEN status = 1 THEN 'Active' WHEN status = 0 THEN 'Inactive' -- 全部返回 VARCHAR2 END FROM users; ``` --- #### 4. **JOIN 条件中的数据类型匹配** - **问题描述** 连接两个表时,如果连接的数据类型同(例如 `VARCHAR2` vs `NUMBER`),会触发此错误: ```sql SELECT * FROM table1 JOIN table2 ON table1.id = table2.id -- table1.id 是 VARCHAR2,table2.id 是 NUMBER ``` - **解决方法** 显式转换数据类型: ```sql SELECT * FROM table1 JOIN table2 ON TO_NUMBER(table1.id) = table2.id; ``` --- #### 5. **INSERT/UPDATE 语句中的值类型匹配** - **问题描述** 插入或更新数据时,如果值的类型与定义匹配: ```sql INSERT INTO products (id, price) VALUES ('100', '99.99'); -- id 是 NUMBER,但 '100' 是字符串 ``` - **解决方法** 确保传入值的类型与定义一致: ```sql INSERT INTO products (id, price) VALUES (100, 99.99); ``` --- ### 排查步骤 1. **定位报错的 SQL 语句** 根据日志找到具体报错的 SQL(例如 MyBatis 的 XML 映射文件或动态 SQL)。 2. **检查集合操作、IN 子句、CASE WHEN 等关键点** 确保对应表达式类型一致。 3. **验证表结构** 使用 `DESC table_name` 确认相关的数据类型。 4. **检查动态参数类型** 如果使用 MyBatis,确认 `#{}` 传入的参数类型与数据库类型匹配。 --- ### 示例调试 假设错误出现在以下 SQL: ```sql SELECT employee_id, hire_date FROM employees UNION SELECT employee_id, salary FROM employees; ``` - **问题**:`hire_date` 是 `DATE` 类型,而 `salary` 是 `NUMBER` 类型。 - **修复**: ```sql SELECT employee_id, TO_CHAR(hire_date) FROM employees UNION SELECT employee_id, TO_CHAR(salary) FROM employees; ``` --- 通过以上步骤,逐步检查并统一数据类型即可解决该错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值