I am Retrieving some tables from database and storing those table names in a hashset. Code I am using to retrieve table is as follows
DatabaseMetaData md = conn.getMetaData();
ResultSet rs = md.getTables(null, null, "%", null);
while (rs.next()) {
hash. add(rs. getString(3) ) ;
}
Now I have tables in a hash set.
Now I want to retrieve data from all these tables in a hash set for particular column 'student'. And put all values in a list. I want to retrieve all distinct values of column student in all these tables. Table may contain or may not contain this student column. If a table contains this column then I want to store its distinct values in a list. Please suggest how to do it.
Note that you can not extract table data using the databasemetadata. Databasemetadata will only provide you the details of table like name, columns, datatypes etc. You need to make the JDBC connection with the database and then need to fire the select query to get the desired result.
Below is the simple JDBC program to do so:
DatabaseMetaData md = conn.getMetaData();
// get tables from database
ResultSet rs = md.getTables(null, null, "%", null);
while (rs.next()) {
hash. add(rs. getString(3) ) ;
}
// getColumns of table 'tableName'
ResultSet rs2 = md.getColumns(null, null, tableName, null);
boolean found = false;
while (rs2.next()) {
String columnName = rs2.getString("COLUMN_NAME");
if (columnName.equalsIgnoreCase("student")) {
found = true;
break;
}
}
if (found) {
String driver = "provide the driver for database here like com.mysql.....";
String url = "provide the connection url here like jdbc://...."
String userName = "provide DB username"
String password = "provide DB username"
Class.forName(driver)
Connection conn = DriverManager.getConnection(url, userName, password)
Statement st = conn.createStatement();
Resultset rs3 = null;
// Now take the tableName from your hashset and pass it into below query.
String query = "select student from " + tableName;
rs3 = st.executeQuery(query);
While(rs3.next()) {
// Store the results anywhere you want by obtaining 'rs3.getString(1)'
}
}
Hope this resolves your problem. Please ignore typos in code if any.
Related
So, I'm trying to extract msgID and msgStatus values from database for each reference Id(variable msgRefList) stored in the list object and I'm trying to store these extracted values in String objects for further processing. But rs.next() method is returning false and hence it is not going into the while loop where the assignment statements are. I checked in database with the query that i'm using in the code and it shows one record in the result, but still rs.next() is returning false. Screenshot attached with the database results.
Below is the actual code that i'm using
List<String> msgRefList = listofRefrnceValues:
try {
Connection connect = connectToDB(ENV);
for(String reference: msgRefList){
String query="select ID, MSG_STS from TABLE where INSTR_ID = ?";
PreparedStatement stmt = connect.prepareStatement(query);
stmt.setString(1,reference);
ResultSet rs = stmt.executeQuery();
if(rs!=null){
while(rs.next()) {
P_MID = rs.getString("P_MID");
P_MSG_STS = rs.getString("P_MSG_STS");
}
}
}
}catch (Exception e) {
e.printStackTrace();
}
You have some typos in your SQL-Query-String in java. Instead of TABLE you probably meant MINF (your real table) also all of your properties don't have the prefix P_ and ID is probably MID. So change:
String query="select ID, MSG_STS from TABLE where INSTR_ID = ?";
To:
String query="select P_MID, P_MSG_STS from MINF where P_INSTR_ID = ?";
And you'll be fine.
I am using Statement.RETURN_GENERATED_KEYS flag to obtan the newly generated primary key value after every insert in the database.
Here is the code snippet:
Connection conn = null;
conn = getDBConnection(); //Susseccfully returns a proper Connection object
PreparedStatement stmt = null;
String sql = "INSERT INTO ..."; //Proper error free INSERT query
stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);//to obtain the new primary key
i = stmt.executeUpdate();//the value of i is always 1 :(
Not able to understand why this is happening. My driver is com.mysql.jdbc.Driver
EDIT: The primary key's data tyoe is BIGINT in the DB and its the second column in the table.
executeUpdate() returns the number of affected rows.
Call stmt.getGeneratedKeys() to get a ResultSet with the generated keys:
long key = -1L;
PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);//to obtain the new primary key
// execute statement
int affectedRows = stmt.executeUpdate();
ResultSet rs = stmt.getGeneratedKeys();
// get generated key
if (rs != null && rs.next()) {
key = rs.getLong(1);
}
I have a DB schema that creates several tables and fills them with data. I want to check whether db contains corresponding tables or not during app start. I could check for db file existence, but H2 creates db if it doesn't exist. So the only way, I think, is to check for tables existence.
Here is the code of how I initialize DB:
Class.forName("org.h2.Driver");
Connection conn = DriverManager.getConnection("jdbc:h2:database/svc", "sa", "");
Statement st = conn.createStatement();
st.execute("CREATE TABLE IF NOT EXISTS table1 (id INT PRIMARY KEY AUTO_INCREMENT NOT NULL, name VARCHAR(100), record INT, record_date DATE, UNIQUE(name))");
st.execute("CREATE TABLE IF NOT EXISTS table2 (id INT PRIMARY KEY AUTO_INCREMENT NOT NULL, name VARCHAR(100), record INT, record_date DATE, UNIQUE(name))");
st.execute("CREATE TABLE IF NOT EXISTS daily_record_stat (id INT PRIMARY KEY AUTO_INCREMENT NOT NULL, date DATE, table1_id INT, table1_record INT, table2_id INT," +
" table2_record INT, total_record INT);");
st.execute("ALTER TABLE daily_record_stat ADD FOREIGN KEY (table1_id) REFERENCES table1(id);");
st.execute("ALTER TABLE daily_record_stat ADD FOREIGN KEY (table2_id) REFERENCES table2(id);");
st.execute("INSERT INTO table1 VALUES(1, 'non_existed_stub', 0, NULL)");
st.execute("INSERT INTO table2 VALUES(1, 'non_existed_stub', 0, NULL)");
conn.close();
As you see, I check for table existence before creation using IF NOT EXISTS statement. But then I run at the problem with ALTER and INSERT - these commands don's allow IF usage.
I tried to do the following:
Connection conn = DriverManager.getConnection("jdbc:h2:database/svc", "sa", "");
ResultSet meta = conn.getMetaData().getTables(null, null, "table1", null);
if(meta.next()) {
//do something
}
But meta.next() is false.
So how to check whether table schema is initialized? Or maybe this should be done some other way?
Not sure if that's what you mean by saying to check programmatically, buy you can try to use DatabaseMetaData.getTables(). This call will return ResultSet which you'll have to check programmatically. You can see what fields are returned in this ResultSet in corresponding section here. And meta data itself can be obtained by conn.getMetaData().
Following code should return all tables which names start with 'TABLE':
ResultSet meta = conn.getMetaData().getTables(null, null, "TABLE%", new String[]{"TABLE"});
while (meta.next()) {
System.out.println(meta.getString(3));
}
Note that you have to specify table name pattern in upper case. Also it's good to pass table types that you need, although it is optional.
This is a check I used to (re)create the H2 database:
// IMPORTANT A sorted list of table names.
private static final String[] REQUIRED_TABLES = { "USER", ... };
public static final String CREATE_USER = "create table USER (...)";
private boolean schemaExists() throws SQLException {
final List<String> requiredTables = Arrays.asList(REQUIRED_TABLES);
final List<String> tableNames = new ArrayList<String>();
final Connection conn = dataSource.getConnection();
try {
final Statement st = conn.createStatement();
final ResultSet rs = st.executeQuery("show tables");
while (rs.next()) {
tableNames.add(rs.getString("TABLE_NAME"));
}
rs.close();
st.close();
}
finally {
if (conn != null) { conn.close(); }
}
Collections.sort(tableNames);
return tableNames.equals(requiredTables);
}
private void initializeDatabase() throws SQLException {
final Connection conn = dataSource.getConnection();
try {
if (schemaExists()) {
return;
}
final Statement st = conn.createStatement();
st.executeUpdate(CREATE_USER);
conn.commit();
}
finally {
if (conn != null) { conn.close(); }
}
}
And you just call:
initializeDatabase();
Notice the list of required tables has to be sorted because I use List.equals() to compare two lists. It would probably be better to also programmatically sort the required tables list too.
It's not fool-proof (not checking if any table exists and if it should be altered) but it works for me.
Take a look at the SHOW command for other uses.
I have the code as follows:
DatabaseMetaData dmd = connection.getMetaData();
ResultSet rs = dmd.getPrimaryKeys(null, null, tableName);
while(rs.next()){
primaryKey = rs.getString("COLUMN_NAME");
}
rs is not null while rs.next() always return false, anyone has idea about it? Thanks.
metadata interface implementation was implemented by driver vendors. It may not be supported by some driver and some db.
Here is text from javadoc:
Some DatabaseMetaData methods return lists of information in the form of ResultSet objects. Regular ResultSet methods, such as getString and getInt, can be used to retrieve the data from these ResultSet objects. If a given form of metadata is not available, an empty ResultSet will be returned.
table name is case sensitive in oracle
or try the below approach
DatabaseMetaData dm = conn.getMetaData( );
ResultSet rs = dm.getExportedKeys( "" , "" , "table1" );
while( rs.next( ) )
{
String pkey = rs.getString("PKCOLUMN_NAME");
System.out.println("primary key = " + pkey);
}
you can also use getCrossReference or getImportedKeys to retrieve primary key
I have a problem with fetching table names from SQL Server 2005. I have succeeded in fetching the table names but the problem is along with the table names VIEWS are also displaying. I need to display only the table names in a dropdown.
My code is:
...
String connectionUrl = "jdbc:sqlserver://localhost:1433;" +
"databaseName="somedb";username=sa;password=1234";
Connection con = null;
Statement st = null;
ResultSet rslt = null;
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
con = DriverManager.getConnection(connectionUrl);
DatabaseMetaData md = con.getMetaData();
ResultSet rrs = md.getTables(null, null, "%", null);
while (rrs.next())
{
System.out.println(rrs.getString(3));
}
Here System.out.println(rrs.getString(3)); statement prints all the table names, but along with view names. I need to avoid printing view names. How can I do it?
you can query to meta data tables on MSSQL server. e.g. select * from sysobjects where xtype = 'u' ;here xtype is type of object and 'u' refers to the table type objects.. see MSSQL server documentation for syntax details
there are two areas:
1/ you not restricted on Db side for view the Metadata
2/ by using aliases return AliasName f.e. Select SomeColumNane as Count returns columnName Count
private ResultSetMetaData metaData; //variable
//intialize rslt("Select .....") and thenarter you can call from rstl
metaData = rslt.getMetaData();
//get Column Class (Varchar, Date, Double....)
String className = metaData.getColumnClassName(column + 1);// packed into try catch finally block
// get column count
int columnCount = metaData.getColumnCount();// packed into try catch finally block
//get Column Name
String columnName = metaData.getColumnName(column + 1);// packed into try catch finally block