【问题标题】:A character string to numeric conversion failed while using syntax like 'OPE' =?使用像“OPE”这样的语法时,字符串到数字的转换失败=?
【发布时间】:2020-05-04 14:22:39
【问题描述】:

我尝试使用 Spring JDBC 模板运行此查询

  public static String FIND_CNC_OPE_GRAPPE_BY_FCT_ID = 
        "SELECT "
                    +"EXPO.COD_NAT_XPN "
                    +", EXPO.IDF_TEC_XPN "
                    +", EXPO.IDF_FCT_XPN_RIS "
                    +", EXPO.DAT_PRM_IPE_LC_CEC  "
        +"FROM  T_CCA_EXPO EXPO "
        +"WHERE "
        + " 'OPE' = ? ";

为此,我使用这个 java 代码:

  import java.sql.Connection;
  import java.sql.PreparedStatement;
  import java.sql.ResultSet;
  import java.sql.SQLException;
  import java.util.ArrayList;
  import java.util.List;

  import org.apache.commons.lang3.StringUtils;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.jdbc.core.JdbcTemplate;
  import org.springframework.stereotype.Repository;

  import lombok.extern.slf4j.Slf4j;

  @Repository
  @Slf4j
  public class ContractGrappeRepository implements ContractGrappeInterfaceRepository {

       static String query = GrappeQueryConstant.FIND_CNC_OPE_GRAPPE_BY_FCT_ID;

       @Autowired
       private JdbcTemplate baseJDBCTemplate;

       private Connection dbConnection;

       private PreparedStatement statement = null;

       private ResultSet dealResultSet;

       @Override
       public ResultSet findGrappeByDealFctID() {

       try {
          dbConnection = baseJDBCTemplate.getDataSource().getConnection();
          statement = dbConnection.prepareStatement(query);
          statement.setString(1,"AKA");
          dealResultSet = statement.executeQuery();
       } catch (SQLException e) {
          throw new RestructNumberException("Exception while fetching contracts",e);
       }

       return null; // TO MODIFY
   }

 }

当编译器到达这一行时 dbConnection.prepareStatement(query);我收到此错误消息;

   java.sql.SQLException: [Teradata Database] [TeraJDBC 16.00.00.24] [Error 3535] [SQLState 22003] A character string failed conversion to a numeric value.
at com.teradata.jdbc.jdbc_4.util.ErrorFactory.makeDatabaseSQLException(ErrorFactory.java:309)
at com.teradata.jdbc.jdbc_4.statemachine.ReceiveInitSubState.action(ReceiveInitSubState.java:103)
at com.teradata.jdbc.jdbc_4.statemachine.StatementReceiveState.subStateMachine(StatementReceiveState.java:311)
at com.teradata.jdbc.jdbc_4.statemachine.StatementReceiveState.action(StatementReceiveState.java:200)
at com.teradata.jdbc.jdbc_4.statemachine.StatementController.runBody(StatementController.java:137)
at com.teradata.jdbc.jdbc_4.statemachine.StatementController.run(StatementController.java:128)
at com.teradata.jdbc.jdbc_4.TDStatement.executeStatement(TDStatement.java:389)
at com.teradata.jdbc.jdbc_4.TDStatement.prepareRequest(TDStatement.java:576)
at com.teradata.jdbc.jdbc_4.TDPreparedStatement.<init>(TDPreparedStatement.java:128)
at com.teradata.jdbc.jdk6.JDK6_SQL_PreparedStatement.<init>(JDK6_SQL_PreparedStatement.java:30)
at com.teradata.jdbc.jdk6.JDK6_SQL_Connection.constructPreparedStatement(JDK6_SQL_Connection.java:82)
at com.teradata.jdbc.jdbc_4.TDSession.prepareStatement(TDSession.java:1330)
at com.teradata.jdbc.jdbc_4.TDSession.prepareStatement(TDSession.java:1374)
at com.teradata.jdbc.jdbc_4.TDSession.prepareStatement(TDSession.java:1360)
at com.teradata.jdbc.jdbc.ManagerConnectionBase.prepareStatement(ManagerConnectionBase.java:294)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)

当我在 Terdata sql 助手上运行查询时,我没有任何错误。 但是当我在查询中更改 where 子句时

    +"WHERE "
    + " 'OPE' = ? ";

    +"WHERE "
    + " 'OPE' = EXP.COD_NAT_XPN ";

我没有任何错误,

为什么 java 不接受这种语法 'OPE' = ?

我正在使用 Spring boot 1.5.9.RELEASE

Teradata 版本 16.00.00.24

【问题讨论】:

  • 您是否尝试将列作为变量传递?并始终将其与字符串 'OPE'? 进行比较
  • 去掉问号就不能保留statement.setString(1,"AKA");
  • 根据您的 SQL 助手版本、连接方法和选项设置,SQLA 可能会在将查询传递给驱动程序之前进行简单的文本替换(实际上是“动态 SQL”)。另一方面,绑定参数只能用于传递值,不能更改查询中使用的标记(例如列名)。
  • 所以我不能在我的查询@Fred 中使用这个语法?
  • @Andre 不,我尝试检查变量值而不是列名作为变量

标签: java spring spring-boot teradata


【解决方案1】:

将 statement.setString(1,"AKA") 更改为 setInt

编辑:

statement = dbConnection.prepareStatement(query);

由于遵循规则 link,TeraData 正在尝试编译您的 SQL 查询,因此您遇到了错误。

对于您的问题,我找到了解决方案here。你应该做的是改变查询如下:

" 'OPE' = cast(? as number) ";

【讨论】:

  • 我收到了新的错误消息 [错误 3784] [SQLState 42000] 指定的位数必须在 1 到 38 之间。当我使用这个时“'OPE' = cast(? as number(60 )) ";,问题不同,java 不接受 'charsequence' = ?param 的语法
  • 你为什么用60?我们可以使用 1 到 38 之间的数字吗?
  • 当我将 38 改为 60 时出现第一个错误 [TeraJDBC 16.00.00.24] [错误 3535] [SQLState 22003] 字符串转换为数值失败。
【解决方案2】:

将 JDBC 对象放在ContractGrappeRepository 的字段中是危险的;它们必须关闭,并且不能共享每个实例。

   try (Connection dbConnection = baseJDBCTemplate.getDataSource().getConnection();
          Prepared statement = dbConnection.prepareStatement(query)) {
      statement.setString(1,"AKA");
      try (ResultSet dealResultSet = statement.executeQuery()) {
          while (dealResultSet.next()) {
              ...
          }
          return ...
      }
   } catch (SQLException e) {
      throw new RestructNumberException("Exception while fetching contracts",e);
   }

有一个概念错误:? 是一个值的占位符,结果是

'OPE' = 'AKA'               ***WRONG***

所以你需要一个列比较 concatenate/String.format 的 SQL 字符串:

     statement = dbConnection.prepareStatement(query.replace("?", "AKA"));

【讨论】:

  • 'OPE' = 'AKA' 也没有被接受,我现在测试了!
  • 做一个干净的构建,调试/记录query的值。
  • 选择 EXPO.COD_NAT_XPN , EXPO.IDF_TEC_XPN , EXPO.IDF_FCT_XPN_RIS , EXPO.DAT_PRM_IPE_LC_CEC FROM T_CCA_EXPO EXPO WHERE ('OPE'='AKKA')
  • 如果 AKA(或 AKKA)是列名,则 SQL 语法不需要引号或引号(双引号)“”。将值放在撇号(单引号)中 ' ' 表示字符串文字。 “不接受”是什么意思。如果您收到语法错误,请发布。如果您收到意外结果(即没有行),请说明。
  • No AKA 不是列,它是一个简单的字符串,正如我所说,当我尝试运行此示例查询时,我收到错误字符串转换为数值失败。我的查询太长了,我有很多 OR 语句,但问题是 'some string' = 'some string'
猜你喜欢
  • 2021-01-04
  • 1970-01-01
  • 2017-04-30
  • 2011-02-19
  • 2012-09-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多