views:

2099

answers:

5

Is there a general, cross RDMS, way I can have a key auto generated on a JDBC insert? For example if I have a table with a primary key, id, and an int value:

create table test (
  id int not null,
  myNum int null
)

and do an insert

PreparedStatement statement = connection.prepareStatement("insert into test(myNum) values(?)", Statement.RETURN_GENERATED_KEYS);
statement.setInt(1, 555);
statement.executeUpdate();
        statement.close();

I get an java.sql.SQLException: Cannot insert the value NULL into column 'id'.

I have a feeling this is entirely RDMS dependent. We are using using SQL Server 2005 and I have set

CONSTRAINT [PK_test] PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 1) ON [PRIMARY]

in the table with no luck.

+1  A: 

As far as I know it's database dependent. Likewise with inserting timestamps; some will insert the current time when you insert a null.

lumpynose
+2  A: 

You need to set the id column in the test table to autocreate an identity. In the case of SQL Server, you need to set the IDENTITY() property on the ID column.

McWafflestix
+2  A: 

This is database dependant. Oracle requires a SEQUENCE to be created and on MySQL you just set the column as auto increment.

You could always use Hibernate.

Peter D
To explain it a bit more - using Hibernate you could generate the DDL or even let Hibernate create all mapped tables on startup. You would just have to tell Hibernate the target database using the appropriate "dialect".
rudolfson
+2  A: 

This is completely database dependent. There are two main options: 1 - DBMSs that allow an auto-increment keyword next to the primary key definition and 2 - DBMSs that provide sequence generators (that you then can use to generate the new values for the PK, for instance by writing a "before insert" trigger that automatically inserts the new value in the column before completing the insertion ).

As far as I know:

  1. Firebird uses sequences
  2. DB2 allows to define a column as "GENERATED BY DEFAULT AS IDENTITY";
  3. Interbase uses sequences (called generators)
  4. MySQL has the "AUTO_INCREMENT" clause
  5. Oracle uses sequences
  6. PostgreSQL uses sequences
  7. SQLServer has the "IDENTITY(1,1)" clause
Jordi Cabot
For DB2 you can choose between an identity column and a sequence. I could image this counts for other rdbms', too.
rudolfson
Thanks for the clarification. However this does not count for other rdbms. At least not for Oracle.
Jordi Cabot
A: 

Thank you all for the answers. It is RDMS dependent then and for SQL Server the correct table create syntax is

create table test (
  id int identity(1,1) not null,
  myNum int null
)

identity(a,b) means that the first key will be a and keys will be incremented by b.

Nash0