How can I detect a SQL table's existence in Java? - java

How can I detect if a certain table exists in a given SQL database in Java?

You can use DatabaseMetaData.getTables() to get information about existing tables.
This method works transparently and is independent of the database engine. I think it queries information schema tables behind the scenes.
Edit:
Here is an example that prints all existing table names.
DatabaseMetaData md = connection.getMetaData();
ResultSet rs = md.getTables(null, null, "%", null);
while (rs.next()) {
System.out.println(rs.getString(3));
}

Use java.sql.DatabaseMetaData.getTables(null, null, YOUR_TABLE, null). If the table exists, you will get a ResultSet with one record.
See DatabaseMetaData.getTables

For ALL ANSI-compliant databases:
(mySQL, SQL Server 2005/2008, Oracle, PostgreSQL, SQLLite, maybe others)
select 1 from information_schema.tables where table_name = #tableName

This is not a language-specific, but a database-specific problem. You'd query the metadata in the database for the existence of that particular object.
In SQL Server for instance:
SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[table]')
AND type in (N'U')

Write a query that queries the table/view that will list the tables (this is different depending on DB vendor). Call that from Java.
Googling information_schema.tables will help a lot.

Depending on the DB, you can do (MySQL)
SHOW TABLES
or (Oracle)
SELECT * FROM user_objects WHERE object_type = 'TABLE'
or another thing for SQL Server. Cycle through the results for MySQL or further filter on the Oracle one.

Why not just see if it is in sysobjects (for SQL Server)?
SELECT [name] FROM [sysobjects] WHERE type = 'U' AND [name] = 'TableName'

There is a JDBC feature, database vendor independent - see [java.sql.DatabaseMetaData#getTables()][1]
You can get the DatabaseMetaData instance by calling java.sql.Connection#getMetaData()
[1]: http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html#getTables(java.lang.String, java.lang.String, java.lang.String, java.lang.String[])

This is what worked for me for jdbc:derby:
//Create Staff table if it does not exist yet
String tableName = "STAFF";
boolean exists = conn.getMetaData().getTables(null, null, tableName, null).next();
if(!exists){
s = conn.createStatement();
s.execute("create table staff(lastname varchar(30), firstname varchar(30), position varchar(20),salary double,age int)");
System.out.println("Created table " + tableName);
}
Note that tableName has to be all caps.

For MS Access:
Select Count(*) From MSysObjects
Where type=1 And name='your_table_name_here'

Related

Selecting default value SQL management studio

I have SQL Server and I am using SQL management studio. What I want is to select default value of column of multiple tables in database.
For example I have database DB. In DB I have 3 tables - tableA, tableB and tableC.
All of them have the same columns. What I want is to get default values of columns 'Customers' for tables A,B and C.
It must be something like this:
SELECT Column_Default
FROM Information_Schema.Columns
WHERE Table_Schema = DB AND
Table_Name like 'table%' and
Column_Name = 'Customers'
But there is error in Table_Schema = DB. I am not sure it should look like this as SQL syntax. It is working as MySQL but not here.
SELECT COLUMN_DEFAULT
FROM Information_Schema.Columns
WHERE Table_Schema = 'dbo'
AND TABLE_NAME IN ('A','B','C')
AND COLUMN_NAME = 'Customers'
You were close, you just needed single quotes around your table schema name, also using the IN operator to explicitly specify your table names instead of using your wildcard search can make the query more robust if if a new table of a similar name is created.

Run Oracle query from Java

I want to run the query: "DESCRIBE table_name;"
statement = this.connection.createStatement();
ResultSet rset = statement.executeQuery("DESCRIBE table_name");
and I got this error:
" java.sql.SQLSyntaxErrorException: ORA-00900: invalid SQL statement"
what is the problem?
DESC[RIBE] is a SQL*Plus command, not a SQL statement. The DESC command queries the Oracle data dictionary, something like:
select COLUMN_NAME, DATA_TYPE
from USER_TAB_COLUMNS
where TABLE_NAME = 'YOUR_TABLE'
DESC is a SQL*Plus command. SO, you cannot use it via JDBC/ODBC.
An alternative can be like this below.
select RPAD(COLUMN_NAME,30)||' '||DATA_TYPE||'('||DATA_LENGTH||')' as descr
FROM all_tab_cols
WHERE TABLE_NAME = UPPER('YOUR_TABLE') and owner=UPPER('SCHEMA_NAME');
all_tab_cols is a data dictionary table(view) which contains the table metadata
Oracle's Reference
describe user2.flights;
Here user2 is database name and flights is table name. Try this.
Or use next query
select *
from user_tab_columns
where table_name = 'MY_TABLE'
order by column_id;
Use this query.
column_id is the "order" of the column in the table.
You should ensure that 'MY_TABLE' is capitalised unless you've been adding tables with casing ( a bad idea ) in which case you need to use something like = "MyTable"

ResultSetMetaData getting default value of column

I am Using Oracle database.
I want to get default value assign to column using Java JDBC.
But using ResultSetMetaData does not provide any method to get default value of column.
So please tell me any idea.
Thanks in advance.
You can run this query
Select DATA_DEFAULT from USER_TAB_COLUMNS where TABLE_NAME ='MyTable' and COLUMN_NAME = 'MyColumn'
There is no 'getDefaultValue' method on ResultSetMetaData in Java JDBC that I can find.
However the following query works:
SELECT COLUMN_NAME, COLUMN_DEFAULT FROM INFORMATION_SCHEMA.COLUMNS
where table_name='<tablename>' and COLUMN_DEFAULT is not null
Connect to the db in question, or similarly with the db name querying master.
This answer uses DatabaseMetadata rather than ResultSetMetadata, so technically it does not answer the question posed. However, it appears more reliable than a query and still has long-term value for the community at large:
JDBC is there a way to detect if a column has a default?
Example:
Connection connection = ...;
DatabaseMetaData databaseMetaData = connection.getMetaData();
try (ResultSet resultSet = databaseMetaData.getColumns(null, null, "MyTable", "MyColumn")) {
while (resultSet.next()) {
String defaultValue = resultSet.getString("COLUMN_DEF");
// Do something...
}
}
below function Returns the default value of a column.
call it on your ResultSetMetaData
public java.lang.String getDefaultValue(int columnIndex) // or columnName
throws DriverException
like ResultSetMetaData.getDefaultValue(columnNameOrcolumnIndex)

sql-server jdbc4 drivers doesn't list all columns?

I have a (sql server) column which have a System Type but no Data Type (It is actually more then one). Using the Microsoft jdbc4 drivers and trying to list all the columns using metadata for this table this column with the missing Data type doesn't show up:
ResultSet rs = connection.getMetaData().getColumns(null,"schema","tableName", null);
while (rs.next()) {
String column = rs.getString("COLUMN_NAME");
System.out.println("column:" + column); // This will not print the column
}
If you use the odbc drivers, in for example C#, it does show up (The column with the missing Data Type). And if this column is a constraint it will show up when using the the jdbc api for listing all constraints:
ResultSet rs = connection.getMetaData().getIndexInfo(null,
"schema",
"tableName",
true/*list unique*/,
true);
while(rs.next()){
String column = rs.getString("COLUMN_NAME");
System.out.println("column:" + column); // This will print the column, if it is a unique constraint.
}
This behavior is the same regardless if you use jdbc4 drivers or the jtds drivers.
So my question is, if this is a bug or is it something that I'm missing? And Is it possible to list the meta data in an other way to get all the columns for table?
To create a Table which doesn't display a Data Type. This demands that you create a user which haven't read access to the user defined Data Types. This is how can reproduce it:
I found this code here
CREATE TYPE TEST_TYPE2 FROM [int] NOT NULL
GO
CREATE TABLE Customer
(
CustomerID INT IDENTITY(1,1) NOT NULL,
LastName VARCHAR(100) NOT NULL,
FirstName VARCHAR(100) NOT NULL,
ZIP TEST_TYPE2 NOT NULL
)
GO
-- Create Table without UDDT
CREATE TABLE Customer_Orig
(
CustomerID INT IDENTITY(1,1) NOT NULL,
LastName VARCHAR(100) NOT NULL,
FirstName VARCHAR(100) NOT NULL,
ZIP INT NOT NULL
)
GO
-- Create User with db_datareader to database
USE [master]
GO
CREATE LOGIN testUser WITH PASSWORD=N'THE_PASSWORD',
DEFAULT_DATABASE=[master],
CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF
GO
USE TEST_DATABASE
GO
CREATE USER testUser FOR LOGIN testUser
GO
USE TEST_DATABASE
GO
EXEC sp_addrolemember N'db_datareader', N'THE_PASSWORD'
GO
I understand why it doesn't show up, but I way does it work for the odbc drivers?

Primary key from inserted row jdbc?

Is there a cross database platform way to get the primary key of the record you have just inserted?
I noted that this answer says that you can get it by Calling SELECT LAST_INSERT_ID() and I think that you can call SELECT ##IDENTITY AS 'Identity'; is there a common way to do this accross databases in jdbc?
If not how would you suggest I implement this for a piece of code that could access any of SQL Server, MySQL and Oracle?
Copied from my code:
pInsertOid = connection.prepareStatement(INSERT_OID_SQL, Statement.RETURN_GENERATED_KEYS);
where pInsertOid is a prepared statement.
you can then obtain the key:
// fill in the prepared statement and
pInsertOid.executeUpdate();
ResultSet rs = pInsertOid.getGeneratedKeys();
if (rs.next()) {
int newId = rs.getInt(1);
oid.setId(newId);
}
Hope this gives you a good starting point.
extraneon's answer, although correct, doesn't work for Oracle.
The way you do this for Oracle is:
String key[] = {"ID"}; //put the name of the primary key column
ps = con.prepareStatement(insertQuery, key);
ps.executeUpdate();
rs = ps.getGeneratedKeys();
if (rs.next()) {
generatedKey = rs.getLong(1);
}
Have you tried the Statement.executeUpdate() and Statement.getGeneratedKeys() methods? There is a developerWorks article that mentions the approach.
Also, in JDBC 4.0 Sun added the row_id feature that allows you to get a unique handle on a row. The feature is supported by Oracle and DB2. For sql server you will probably need a third party driver such as this one.
Good luck!
for oracle, Hibernate uses NEXT_VALUE from a sequence if you have mapped a sequence for PKEY value generation.
Not sure what it does for MySQL or MS SQL server
Spring provides some useful support for this operation and the reference guide seems to answer your question:
There is not a standard single way to
create an appropriate
PreparedStatement (which explains why
the method signature is the way it
is). An example that works on Oracle
and may not work on other platforms
is...
I've tested this example on MySQL and it works there too, but I can't speak for other platforms.
For databases that conform to SQL-99, you can use identity columns:
CREATE TABLE sometable (id INTEGER GENERATED ALWAYS AS IDENTITY(START WITH 101) PRIMARY KEY, ...
Use getGeneratedKeys() to retrieve the key that was just inserted with executeUpdate(String sql, int autoGeneratedKeys). Use Statement.RETURN_GENERATED_KEYS for 2nd parameter to executeUpdate()
Just declare id column as id integer not NULL primary key auto_increment
after this execute this code
ResultSet ds=st.executeQuery("select * from user");
while(ds.next())
{
ds.last();
System.out.println("please note down your registration id which is "+ds.getInt("id"));
}
ds.close();
the above code will show you the current row's id
if you remove ds.last() than it will show all values of id column

Categories