Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change datatype of a sequence H2DB

Tags:

java

oracle

h2

I need to change the returned value of a sequence stored into a H2DB, when i call nextVal through a direct SQL query H2 return a BigInt and i need a BigDecimal.

I can't cast or convert this value, I need H2 returning a BigDecimal.

How I can do that?

EDIT: I can't change the Java code beacuse I'm testing so cast or convert the request value from DB is not a option.

like image 608
CrowDev Avatar asked May 21 '15 11:05

CrowDev


People also ask

How do I change datatype in H2 database?

Alter Table Alter Column. This command is used to change the structure and properties of the column of a particular table. Changing the properties means changing the datatype of a column, rename a column, change the identity value, or change the selectivity.

How do you make a H2 case insensitive?

However H2 supports case insensitive columns as well. To create the tables with case insensitive texts, append IGNORECASE=TRUE to the database URL (example: jdbc:h2:~/test;IGNORECASE=TRUE ).

How do you persist data in H2 DB?

Persist the data in H2 Database If we want to persist the data in the H2 database, we should store data in a file. To achieve the same, we need to change the datasource URL property. In the above property, the sampledata is a file name.


2 Answers

You could create you own patched version of H2, if you are allowed to replace the H2 jar file.

In org.h2.expression.Function change

    addFunctionNotDeterministic("NEXTVAL", NEXTVAL,
            VAR_ARGS, Value.LONG); 

to

    addFunctionNotDeterministic("NEXTVAL", NEXTVAL,
            VAR_ARGS, Value.DECIMAL);

and in org.h2.expression.SequenceValue change

@Override
public Value getValue(Session session) {
    long value = sequence.getNext(session);
    session.setLastIdentity(ValueLong.get(value));
    return ValueLong.get(value);
}

@Override
public int getType() {
    return Value.LONG;
} 

to

@Override
public Value getValue(Session session) {
    long lv = sequence.getNext(session);
    ValueDecimal value = ValueDecimal.get(BigDecimal.valueOf(lv)); 
    session.setLastIdentity(value);
    return value;
}

@Override
public int getType() {
    return Value.DECIMAL;
} 
like image 72
wero Avatar answered Oct 03 '22 02:10

wero


I've tried to take the code from wero's answer and make this into a feature in H2 itself.

This GitHub fork: https://github.com/portofrotterdam/h2database returns BigDecimals instead of BigInteger/longs when using 'MODE=Oracle' in H2, making it more compatible with Oracle's database.

I've requested a pull to the master so perhaps this behaviour will be available in h2database.

like image 23
Roy van Rijn Avatar answered Oct 03 '22 01:10

Roy van Rijn