【问题标题】:H2 Oracle decode functionH2 Oracle 解码功能
【发布时间】:2011-11-20 19:35:27
【问题描述】:

在H2中,我写了一个Java解码函数。它适用于代码:

String sql = "select decode(1.0,2.0,3.0,4.0) from dual ;";
PreparedStatement stmt = connection.prepareStatement(sql);
ResultSet resultSet = (ResultSet) stmt.executeQuery();

但是代码

String sql = "select 6.0 - decode(1.0,2.0,3.0,4.0) from dual ;";

给出错误:

org.h2.jdbc.JdbcSQLException: Hexadecimal string with odd number of characters: "6.0"; SQL statement:
select 6.0 - decode(1.0,2.0,3.0,4.0) from dual ; [90003-157]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:327)
    at org.h2.message.DbException.get(DbException.java:167)
    at org.h2.message.DbException.get(DbException.java:144)
    at org.h2.util.StringUtils.convertHexToBytes(StringUtils.java:943)
    at org.h2.value.Value.convertTo(Value.java:826)
    at org.h2.expression.Operation.getValue(Operation.java:108)
    at org.h2.command.dml.Select.queryFlat(Select.java:518)
    at org.h2.command.dml.Select.queryWithoutCache(Select.java:617)
    at org.h2.command.dml.Query.query(Query.java:298)
    at org.h2.command.dml.Query.query(Query.java:268)
    at org.h2.command.dml.Query.query(Query.java:37)
    at org.h2.command.CommandContainer.query(CommandContainer.java:80)
    at org.h2.command.Command.executeQuery(Command.java:181)
    at org.h2.jdbc.JdbcPreparedStatement.executeQuery(JdbcPreparedStatement.java:96)

我的解码功能如下:

public final static Value decode(Value expression, Value ... paramValues) {
    boolean param = true;
    boolean hit = false;
    Value returnValue = null;
    Value defaultValue = null;
    // Walk through all parameters, alternately the 'param' and corresponding 'value'.
    // If 'param' is equal the expression, then return the next 'value'.
    // If no hit, the return the last 'param' value as default value.
    for (Value str : paramValues) {
       if (param) {
          defaultValue = str; // In case this is the last parameter.
          // Remember the hit. The next value will be returned.
          hit = (MiscUtil.equals(expression, str)); 
       } else {
          if (hit) {
             returnValue = str;
             break; // return str;
          }
          defaultValue = null;
       }
       param = ! param;
    }
    return (returnValue==null) ? defaultValue : returnValue;
 }

我的解码功能有什么问题吗?


我尝试在解码函数中返回 Object 而不是 Value,并在末尾添加了这段代码:

Object returnObject=null;
if (returnValue instanceof ValueDecimal) {
    returnObject = ((ValueDecimal)returnValue).getBigDecimal();
} else if (returnValue instanceof ValueString) {
    returnObject = ((ValueString)returnValue).getString();
} else if (returnValue instanceof ValueDate) {
    returnObject = ((ValueDate)returnValue).getDate();
}
return returnValue;

但我得到了:

org.h2.jdbc.JdbcSQLException: Data conversion error converting "aced0005737200146a6176612e6d6174682e426967446563696d616c54c71557f981284f0300024900057363616c654c0006696e7456616c7400164c6a6176612f6d6174682f426967496e74656765723b787200106a6176612e6c616e672e4e756d62657286ac951d0b94e08b020000787000000001737200146a6176612e6d6174682e426967496e74656765728cfc9f1fa93bfb1d030006490008626974436f756e744900096269744c656e67746849001366697273744e6f6e7a65726f427974654e756d49000c6c6f776573745365744269744900067369676e756d5b00096d61676e69747564657400025b427871007e0002fffffffffffffffffffffffefffffffe00000001757200025b42acf317f8060854e0020000787000000001287878"; SQL statement:
select 6.0 - cast(decode(1.0,2.0,3.0,4.0) as double) xxx from dual ; [22018-157]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:327)
    at org.h2.message.DbException.get(DbException.java:156)
    at org.h2.value.Value.convertTo(Value.java:855)
    at org.h2.expression.Function.getSimpleValue(Function.java:733)
    at org.h2.expression.Function.getValueWithArgs(Function.java:893)
    at org.h2.expression.Function.getValue(Function.java:432)
    at org.h2.expression.Operation.getValue(Operation.java:113)
    at org.h2.expression.Alias.getValue(Alias.java:35)
...

我也尝试过使用 ValueExpression,但没有运气。

完全支持 H2 中的解码将是最好的解决方案。你可以提供给托马斯吗?

【问题讨论】:

标签: h2


【解决方案1】:

H2认为数据类型为JAVA_OBJECT,因此要将参数(6.0和解码结果)转换为JAVA_OBJECT,即先转换为字节数组。这失败了。

我自己没有测试过,但是显式 CAST 应该可以工作:

select 6.0 - cast(decode(1.0,2.0,3.0,4.0) as double) from dual

我知道这有点丑。

【讨论】:

  • 您的建议给出了完全相同的例外。如果我在解码中移动“6.0 -”,它可以正常工作:select decode(1.0, 2.0, 6.0-3.0, 6.0-4.0) from dual 但是我们在许多视图和 SQL 调用中有很多这样的结构,所以它是一个找到和改变所有这些的糟糕解决方案。有没有办法对 DECODE 函数进行编码以处理 '6.0 - decode(...'?
  • 对不起,你的建议有效!!!但我仍然想要另一种解决方案来避免更改我的代码。
  • 一种可能的解决方案是将对decode 的支持添加到H2 数据库本身中。另一种解决方案是提供一种方法来计算函数内的数据类型,而无需运行该函数。
  • 支持 H2 本身的解码对我来说是最好的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-16
  • 2015-08-13
  • 2019-04-02
  • 2014-12-18
  • 2015-08-12
相关资源
最近更新 更多