2011-09-20 160 views
1

在H2,我寫了一個Java的解碼功能。它的工作原理與代碼:H2甲骨文解碼功能

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 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的解碼

完全支持將是最好的解決方案。這是你可以提供托馬斯的東西嗎?

+0

怎麼樣使用標準的SQL ['CASE WHEN'代替proprietery'DECODE'] [1]? [1]:http://stackoverflow.com/questions/1559241/decode-function-in-sql-server –

回答

2

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 

這是一個有點難看,我知道。

+0

你的建議給出了完全相同的例外。如果我在解碼器內部移動'6.0-',它可以正常工作: 從雙重選擇解碼(1.0,2.0,6.0-3.0,6.0-4.0) 但是我們在很多視圖和SQL調用中都有很多這樣的構造,因此找到並更改所有這些是一個不好的解決方案。 有沒有一種方法來編碼DECODE函數來處理'6.0 - 解碼(...'? – SvRekaa

+0

不好意思,你的建議工程!!!但我仍然想要另一種解決方案來避免更改我的代碼 – SvRekaa

+0

一種可能的解決方案將是增加對'decode'支持到H2數據庫本身。另一個解決方案是提供一種方法來計算的函數內的數據類型,而不必運行功能尚未。在H2解碼本身會引起的 –