Saturday, December 21, 2013

How to retrieve the current value of an oracle sequence without increment it?

SELECT last_number
  FROM all_sequences
 WHERE sequence_owner = ''
   AND sequence_name = '';
You can get a variety of sequence metadata from user_sequencesall_sequences anddba_sequences.
These views work across sessions.
EDIT:
If the sequence is in your default schema then:
SELECT last_number
  FROM user_sequences
 WHERE sequence_name = '';
If you want all the metadata then:
SELECT *
  FROM user_sequences
 WHERE sequence_name = '';
Hope it helps...
EDIT2:
A long winded way of doing it more reliably if your cache size is not 1 would be:
SELECT increment_by I
  FROM user_sequences
 WHERE sequence_name = 'SEQ';

      I
-------
      1

SELECT seq.nextval S
  FROM dual;

      S
-------
   1234

-- Set the sequence to decrement by 
-- the same as its original increment
ALTER SEQUENCE seq 
INCREMENT BY -1;

Sequence altered.

SELECT seq.nextval S
  FROM dual;

      S
-------
   1233

-- Reset the sequence to its original increment
ALTER SEQUENCE seq 
INCREMENT BY 1;

Sequence altered.
Just beware that if others are using the sequence during this time - they (or you) may get
ORA-08004: sequence SEQ.NEXTVAL goes below the sequences MINVALUE and cannot be instantiated
Also, you might want to set the cache to NOCACHE prior to the resetting and then back to its original value afterwards to make sure you've not cached a lot of values.

Wednesday, December 11, 2013

What is a serialVersionUID and why should I use it?

The docs for java.io.Serializable are probably about as good an explanation as you'll get:
The serialization runtime associates with each serializable class a version number, called a serialVersionUID, which is used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization. If the receiver has loaded a class for the object that has a different serialVersionUID than that of the corresponding sender's class, then deserialization will result in an InvalidClassException. A serializable class can declare its own serialVersionUID explicitly by declaring a field named "serialVersionUID" that must be static, final, and of type long:
ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
If a serializable class does not explicitly declare a serialVersionUID, then the serialization runtime will calculate a default serialVersionUID value for that class based on various aspects of the class, as described in the Java(TM) Object Serialization Specification. However, it is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected InvalidClassExceptions during deserialization. Therefore, to guarantee a consistent serialVersionUID value across different java compiler implementations, a serializable class must declare an explicit serialVersionUID value. It is also strongly advised that explicit serialVersionUID declarations use the private modifier where possible, since such declarations apply only to the immediately declaring class--serialVersionUID fields are not useful as inherited members.
http://stackoverflow.com/questions/285793/what-is-a-serialversionuid-and-why-should-i-use-it

Tuesday, December 10, 2013

java.util.Date vs java.sql.Date

Congratulations, you've hit my favorite pet peeve with JDBC: Date class handling.
Basically databases usually support at least three forms of datetime fields which are date, time and timestamp. Each of these have a corresponding class in JDBC and each of them extendjava.util.Date. Quick semantics of each of these three are the following:
  • java.sql.Date corresponds to SQL DATE which means it stores years, months and days whilehour, minute, second and millisecond are ignored. Additionally sql.Date isn't tied to timezones.
  • java.sql.Time corresponds to SQL TIME and as should be obvious, only contains information about hour, minutes, seconds and milliseconds.
  • java.sql.Timestamp corresponds to SQL TIMESTAMP which is exact date to the nanosecond (note that util.Date only supports milliseconds!) with customizable precision.
One of the commonest bugs in JDBC drivers in relation to these three types is that the types are handled incorrectly. This means that sql.Date is timezone specific, sql.Time contains current year, month and day et cetera et cetera.

Finally: Which one to use?

Depends on the SQL type of the field, really. PreparedStatement has setters for all three values,#setDate() being the one for sql.Date#setTime() for sql.Time and #setTimestamp() forsql.Timestamp.
Do note that if you use ps.setObject(fieldIndex, utilDateObject); you can actually give a normal util.Date to most JDBC drivers which will happily devour it as if it was of the correct type but when you request the data afterwards, you may notice that you're actually missing stuff.

I'm really saying that none of the Dates should be used at all.

What I am saying that save the milliseconds/nanoseconds as plain longs and convert them to whatever objects you are using (obligatory joda-time plug). One hacky way which can be done is to store the date component as one long and time component as another, for example right now would be 20100221 and 154536123. These magic numbers can be used in SQL queries and will be portable from database to another and will let you avoid this part of JDBC/Java Date API:s entirely.

Friday, December 6, 2013

Checking oracle sid and database name

I presume select user from dual; should give you the current user
and select sys_context('userenv','instance_name') from dual; the name of the instance
I believe you can get SID as SELECT sys_context('USERENV', 'SID') FROM DUAL; (can't to check this now)

Default passwords of Oracle 11g?

It is possible to connect to the database without specifying a password. Once you've done that you can then reset the passwords. I'm assuming that you've installed the database on your machine; if not you'll first need to connect to the machine the database is running on.
  1. Ensure your user account is a member of the dba group. How you do this depends on what OS you are running.
  2. Enter sqlplus / as sysdba in a Command Prompt/shell/Terminal window as appropriate. This should log you in to the database as SYS.
  3. Once you're logged in, you can then enter
    alter user SYS identified by "newpassword";
    
    to reset the SYS password, and similarly for SYSTEM.
See also here.
(Note: I haven't tried any of this on Oracle 11g; I'm assuming they haven't changed things since Oracle 10g.)