I'm working on exporting H2 databases and importing them.  When building 
the necessary create statements, I have code that adds the Primary Key 
Index to the CREATE SQL statement.  It will end up looking something like 
this:

CREATE TABLE admit( 
[rowkey] int identity NOT NULL, 
[firstName] nvarchar(50) NULL, 
[lastName] nvarchar(50) NULL, 
[accountNumber] nvarchar(50) NULL, 
[update_time] timestamp NULL, 
CONSTRAINT [PK_admit] PRIMARY KEY ( 
[rowkey]) 
)

First I get the database metadata (java.sql.DatabaseMetaData) from the 
connection(i.e. connection.getMetaData()).  Then, I figure out the primary 
key by calling metadata.getPrimaryKeys(catalog, schema, name).

Then I want to add the various indexes next, so that I end up with a 
complete set of creation statements like:

CREATE TABLE admit( 
[rowkey] int identity NOT NULL, 
[firstName] nvarchar(50) NULL, 
[lastName] nvarchar(50) NULL, 
[accountNumber] nvarchar(50) NULL, 
[update_time] timestamp NULL, 
CONSTRAINT [PK_admit] PRIMARY KEY ( 
[rowkey]) 
) 
GO 
CREATE NONCLUSTERED INDEX [IX_admit_account_number] ON [admit] ( 
[accountNumber]) 
CREATE NONCLUSTERED INDEX [IX_admit_updatetime] ON [admit] ( 
[update_time])

This will correctly run in H2 creating the table with the correct indexes.

To find the indexes, I use metaData.getIndexInfo(catalog, schema, name, 
false, false) and go through generating SQL statements for each index.  Of 
course, this includes the table's primary key, which I need to screen out 
so that I don't end up trying to insert the primary key again.  When this 
code runs against MsSQL, I can check metaData.getPrimaryKeys(catalog, 
schema, name).getString("PK_NAME") equals metaData.getIndexInfo(catalog, 
schema, name, false, false).getString("INDEX_NAME") to determine which 
index is the primary key.

However, the way H2 is written, these will almost certainly never be the 
same name 
(see 
https://github.com/h2database/h2database/blob/master/h2/src/main/org/h2/jdbc/JdbcDatabaseMetaData.java).
  
The PK_NAME is either CONSTRAINT_NAME, INDEX_NAME depending on whether or 
not CONSTRAINT_NAME is null. INDEX_NAME will always be INDEX_NAME. 

Should they return the same thing?  Is this a defect or was there a reason 
it was done this way (i.e. JDBC specifications, etc.)?

If not, is there another (preferably database agnostic) way to determine 
which index is the primary key?

As a work around, H2 always seems to start the CONSTRAINT_NAME with 
"PRIMARY_KEY_", so I'm detecting that I'm running under H2 and then 
checking for that prefix.

Is there a better way?

Thank you.

Sincerely,
Stephen McCants

-- 
You received this message because you are subscribed to the Google Groups "H2 
Database" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/h2-database.
For more options, visit https://groups.google.com/d/optout.

Reply via email to