【问题标题】:SQLException while trying to insert a double value into Oracle database尝试将双精度值插入 Oracle 数据库时出现 SQLException
【发布时间】:2012-11-13 13:37:26
【问题描述】:

我必须开发一个将一些数据插入 Oracle 数据库的小程序。不幸的是,我在使用 SQL Statement 和执行它时遇到了一些麻烦。这是我正在使用的代码:

db.execute(
    String.format("INSERT INTO tops VALUES (%d, '%s', %d, %f.00, '%s', TO_TIMESTAMP('%s', 'YYYY-MM-DD HH24:MI:SS.FF'))", 
        item.getID(),
        item.getTitle(),
        this.elements,
        item.getSize(),
        item.getEntity(),
        timestamp.toString()));

这是执行应该工作的部分,但我收到以下错误:

java.sql.SQLException: ORA-00913: Zu viele Werte

Google Translate 例外是:

java.sql.SQLException: ORA-00913: Too many values

【问题讨论】:

  • 我认为您可以将引号远离字符串值。
  • 听起来您要插入的值与表架构不匹配。 (值太多)
  • 使用准备好的语句,字符串操作是一个非常糟糕的主意
  • 您应该始终指定要插入的列。否则,一旦有人向表中添加新列,您的代码就会中断。
  • @Colin'tHart:不,他不能离开引号!他使用了一个简单的 SQL 查询字符串,并且没有引号,Java String.format - 不知道这是一个正在组装的 SQL 字符串 - 不会插入引号...

标签: java sql string oracle11g ora-00913


【解决方案1】:

您可以按照 Guallaume 在评论中的建议使用这样的准备好的语句;

PreparedStatement pstmt = null;
Connection conn = null;

try{
     //if you have a method that creates a connection for you.
     conn = getConnection();
     pstmt = conn.prepareStatement("INSERT INTO tops(id, title, elements, size, entity, timeStamp) VALUES(?,?,?,?,?,?)");
     pstmt.setInt(1,item.getID());

     //Assuming that title is a String data type
     pstmt.setString(2,item.getTitle());
     pstmt.setString(3,this.elements);
     pstmt.setDouble(4,item.getSize()); // <--- JDBC will make sure this works

     //assuming Entity data type is String
     pstmt.setString(5,item.getEntity());

     //if your timestamp's string format is 
     //well formed, you may insert as a string.
     pstmt.setString(6,timestamp.toString());
     pstmt.executeUpdate();
}catch(Exception e){
     e.printStackTrace();
}finally{  
     try{
         pstmt.close();
     }catch(Exception e){}

     try{
         conn.close();
     }catch(Exception e){}
 }

【讨论】:

  • 希望排版好一点。如您所见,您需要知道要在准备好的语句查询中插入值的列名。例如INSERT INTO tops(id, title, elements, size, entity, timeStamp) VALUES(?,?,?,?,?,?)" 我假设的列是 id、title、elemets、size、entity 和 timestamp。 VALUES(?,?,?,?,?,?) 告诉 java 值将进入那里。 pstmt.setInt(1,item.getID()); 设置第一个值,pstmt.setString(2,item.getTitle()); 设置第二个值,`pstmt.setString(3,this.elements);` 设置第三个值等等...
【解决方案2】:

不要使用这种语法

INSERT INTO table VALUES (val1, val2, ...)

改用这个

INSERT INTO table (col1, col2, ...) VALUES (val1, val2, ...)

表格可能会发生变化。字段可能会被添加/删除/重新排序 - 如果您的 INSERT 语句再次中断。

当然,正如其他人建议的那样,您应该使用准备好的语句来避免 SQL 注入和语法错误......想象一下,item.getTitle() 是其中的任何一个

"a', 'b";
"a'); DROP TABLE tops;' ...";

【讨论】:

    【解决方案3】:

    你真的应该使用 PreparedStatements,相信我们……

    但是,在这种情况下,问题很可能是您的语言环境使用逗号 (,) 字符作为小数点..

    所以 1/4 变成:0,25,而不是数据库想要的 0.25

    为什么会出现这个问题?

    看看这个:

    INSERT INTO SOMETABLE VALUES ( 0,25 );
    INSERT INTO SOMETABLE VALUES ( 0, 25);
    

    两者都被视为具有 2 值,只是第一个对我们来说并不明显,他们使用逗号作为小数点......所以你必须将逗号改为点,或将语言环境更改为美国。

    正确:

    INSERT INTO SOMETABLE VALUES ( 0.25);
    

    您可以通过提供适当的语言环境使用String.format(Locale l, String format, Object... args) 指定字符串格式的语言环境。

    【讨论】:

    • @LukasEder 我不是天才——我只是有很多奇怪的问题要处理:) 在匈牙利,我们也使用逗号作为小数点...(我确实说过即使在我最尊敬的同事面前大声说出一些非政治正确的表达方式,但当我第一次发现这种情况会引起麻烦时......)
    • @LukasEder 更长(更响亮,更不用说)的版本正是我对这个问题的长篇咆哮:)
    【解决方案4】:

    此格式字符串已更正。

    "INSERT INTO tops VALUES (%f, '%s', %f, %.2f, '%s', TO_TIMESTAMP('%s', 'YYYY-MM-DD HH24:MI:SS.FF'))"
    

    每个参数不要使用很多值,每个参数只使用一个,总共六个值。

    【讨论】:

      猜你喜欢
      • 2020-11-01
      • 2015-02-17
      • 2015-09-29
      • 2021-10-17
      • 2017-05-12
      • 1970-01-01
      • 1970-01-01
      • 2012-04-04
      • 1970-01-01
      相关资源
      最近更新 更多