Getting column names from query - java

consider a query like select a.apple,b.mango,c.orange from A a,B b,C c where ... (Some conditions)
here i need to fetch only the column names based on the query.
apple
mango
orange.
we have a query builder where end user creates/generates any type of query using that, my duty is to select only the column names from the query as above for my further operations.
How can i achieve this, through java code or query?
my db is sql server 2005.

to get the ResultSetMetaData java interface
PreparedStatement ps=con.prepareStatement("select * from your_table_name");
ResultSet rs=ps.executeQuery();
ResultSetMetaData rsmd=rs.getMetaData();
System.out.println("Total columns: "+rsmd.getColumnCount());
System.out.println("Column Name of 1st column: "+rsmd.getColumnName(1));
con.close();

In the case you need only to display the columns name that you already know you can simply put them(column names) directly into the SELECT list :
SELECT apple AS apple ,mango AS mango,orange AS orange
otherwise you can query the information schema service table of SQL Server :
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME=OBJECT_NAME(OBJECT_ID('a')) OR TABLE_NAME=OBJECT_NAME(OBJECT_ID('b')) OR TABLE_NAME=OBJECT_NAME(OBJECT_ID('c'))
With Java and from the original query you can read the column names using ResultSetMetaData object :
ResultSetMetaData rsmd = rs.getMetaData();
String apple = rsmd.getColumnName(1); //Column apple
String mango = rsmd.getColumnName(2);

if you are using eclipseLink you could get the columns names as per this link
JPA/EclipseLink - Retrieve Columns Names

I found a solution for this and it is working fine. Thank you everyone for spending your valuable time.
We can achieve this in 2 ways.
Through Map.
ex:
List> lsMapStringObj = new ArrayList>();
for(Map myMap: lsMapStringObj)
{
for (Map.Entry entry : myMap.entrySet())
{
lsRsult.add(entry.getKey());
}
}
But here if the query returns > 0 rows then only i can fetch the column names.
This gives the solution as i expect (>= 0 rows)
PreparedStatement ps=con.prepareStatement(sQuery);
ResultSet rs=ps.executeQuery();
ResultSetMetaData rsmd=rs.getMetaData();
int numColumns = rsmd.getColumnCount();
for (int i = 1; i <= numColumns; ++i)
{
lsResult.add(rsmd.getColumnName(i));
}
return lsResult;
Finally Got it, Hope it helps to others. Enjoy Programming...!!!

One of the simpler solutions is to tokenize the column names using String.split. It will return an array of columnNames.
String query = "select a.apple,b.mango,c.orange from A a,B b,C c where ... (Some conditions)";
String[] columnNames= query.split(" [fF][rR][oO][mM] ")[0]
.split("[ ]*[sS][eE][lL][eE][cC][tT] ")[1]
.split("[ ]*,[ ]*");
for(int i=0; i<columnNames.length;i++){
System.out.println(i+".)"+columnNames[i]);
}
Output:
{a.apple,b.mango,c.orange} //String array
//Sysout
1.)a.apple
2.)b.mango
3.)c.orange

Related

Effective way to compare database values and expected value

I am using keyword driven framework using excel sheet as test data source.I want to compare database and excepted values for more than 20 SQL queries with different columns and tables.Currently i wrote one keyword for each SQL query. I am looking for more effective way to compare values with reusable assertion function.Currently my code looks like:
public compare_customer_details{
SQL1="select column1, column2...column10 from table A;
ResultSet rs = st.executeQuery(SQL1);
while (rs.next()) {
firstname= rs.getString("a.given_name");
Lastname=rs.getString("a.surname");
dob=rs.getString("a.birthdate");
if(Lastname.equalsIgnoreCase(GetDataFromExcel("LastName"))) {}
...}
Keyword 2- for different keyword:
public compare_Address_details{
SQL2="select column1, column2...column10 from table B;
ResultSet rs = st.executeQuery(SQL2);
while (rs.next()) {
abc= rs.getString("a.abc");
Lastname=rs.getString("a.cde");
if(abc.equalsIgnoreCase(GetDataFromExcel("abc"))) {}
...}
Please suggest effective ways.Thanks.

List of columns in sql query

I have a query using various joins, and I just need the list of columns which are returned by this query. I done it in java, by asking only one row with rownum=1 and getting column name for value.The problem is if there is no data returned by that query.
For ex.
select * from something
and if there is any data returning by this query then it will return col1,col2,col3.
But if there is no data returned by this query, then it will throw error.
What I need is
Is there any way that I can run
desc (select * from something)
or similar to get list of columns returned by query.
It can be in sql or JAVA. Both methods are acceptable.
In my application, user passes the query, and I can add wrapper to the query but I cant modify it totally.
The flow of application is
query from user -> execute by java and get one row -> return list of columns in the result set.
you can use ResultSetMetaData of resultset
for example :
ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM TABLE2");
ResultSetMetaData rsmd = rs.getMetaData();
int countOfColumns = rsmd.getColumnCount();
for(int i = 1; i <= countOfColumns ; i++ )
System.out.println(rsmd.getColumnName(i));
you could maybe convert your query to a view, you can then see the columns in the view by querying user_tab_columns
select * from user_tab_columns
The Oracle equivalent for information_schema.COLUMNS is USER_TAB_COLS for tables owned by the current user, ALL_TAB_COLS or DBA_TAB_COLS for tables owned by all users.
Tablespace is not equivalent to a schema, neither do you have to provide the tablespace name.
Providing the schema/username would be of use if you want to query ALL_TAB_COLS or DBA_TAB_COLS for columns OF tables owned by a specific user. in your case, I'd imagine the query would look something like:
String sqlStr= "
SELECT column_name
FROM all_tab_cols
WHERE table_name = 'users'
AND owner = ' || +_db+ || '
AND column_name NOT IN ( 'password', 'version', 'id' )
"
Note that with this approach, you risk SQL injection.

How to Fetch common column from multiple tables in Database?

Greeting to all smart people around here !!
I have faced a weird interview question regarding SQL.
Qn . If I have 100 tables in Database. I want to fetch common records from Each table.
For example, location is common field in 100 tables. I want to fetch location field from all the tables without mentioning each table name in my SQL query.
Is there any way to do it?
If any possibilities let me know...
get list of tables from db metadata, and then query with each:
Statement stmt = conn.createStatement();
ResultSet locationRs = null;
DatabaseMetaData md = conn.getMetaData();
ResultSet rs = md.getTables(null, null, "%", null);
while (rs.next()) {
locationRs = stmt.executeQuery("SELECT location from "+ rs.getString(3));
System.out.println(locationRs.getString(1));
}
In MSSQL Server you have INFORMATION_SCHEMA.COLUMNS table that contains the column names so you can use group by and having count some value you will get the column name after that you can use pivot to get the values of column names and carry on to it. You will get the ans.
For eg.
Select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS group BY COLUMN_NAME having count(COLUMN_NAME) > 2
By above query you will get the common column names
You can try this for any Number of Tables in a DB :
select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS group by COLUMN_NAME having count(COLUMN_NAME)=(select count(*) from INFORMATION_SCHEMA.TABLES)
My friend has found answer for my question..
To get common column from multiple tables,Use INFORMATION_SCHEMA.COLUMNS and common column name.
Query :
select *from information_schema.columns where column_name='column name'
Hope this will helpful !
I am assuming you already have connection and statemnt object's. Now try the below; it might work for you, if not make some adjustments with loops and conditions. Also, you need to have two ResultSet Objects ex: rs1 and rs2. DatabaseMetaData dbmd = con.getMetaData();
String table[] = {"TABLE"} `;
rs1 = dbmd.getTable(null, null, ".*" ,table);
while(rs1.next()){
String tableFrom = rs1.getString(3) ;
rs2 = dbmd.getColumns(null,null,tableFrom , ".*") ;
while(rs2.next()) {
String locColFrom = rs2.getString(3);
if(locColFrom .equalsIgnoreCase("location"))
stmt.executeQuery(select locColFrom from tableFrom ) ;
}
}
Here's an link to study [Oracle] (http://docs.oracle.com/javase/7/docs/api/java/sql/DatabaseMetaData.html#getTables(java.lang.String,%20java.lang.String,%20java.lang.String,%20java.lang.String[]))

ResultSet to ArrayList<String[]>

I want to create an array for each row.
while (result.next()) {
String[] result1 = {
"Dog ID: " + result.getLong("dogs.id"),
", Dog name: " + result.getString("dogs.first_name"),
", Owner name: "
+ result.getString("owners.first_name"),
", Owner phone: " + result.getString("owners.phone") };
resultList.add(result1);
My code write every one row in one array.
Can i get numbers of columns and put a limit?
while (resultset.next()) {
int i = 1;
while(i <= numberOfColumns) {
It's because i can't send entire table as a result from server to client.
You can query by column number result.getLong(columnIndex) but it doesn't make sense in your case withing a loop because you have columns of different types (unless complicating the code).
If you want to optimize the traffic from server to client the way to go is querying for just the columns you need.
If you want to limit the rows returned, it might be better to put the limiting criteria into the SQL query and only return the rows you want to include.
In order to get number of columns in your ResultSet you can use the following piece of code :
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery(myQuery);
ResultSetMetaData metaData = rs.getMetaData();
int numOfColumns = metaData .getColumnCount();

arraylist in insert query

i am trying to insert data from excel sheet into database in java. for that i have connected both the database using ODBC. excelsheet has 2 columns cname and title.
after querying the Excel spreadsheet i stored the resultSet values of cname and title into arraylist.
List Cname = new ArrayList();
List Title=new ArrayList();
Cname.add(rs.getString("Cname"));
Title.add(rs.getString("Title"));
this will result like this
[aaa, bbb,cccc, dddd]
[tree,human,animal,bird]
when i try to insert this into SQL database using insert query it is getting stored like this.
statement1.executeUpdate("INSERT INTO dbo.company (Cname,Title) SELECT
'"+Cname+"','"+Title+"'");
Cname Title
[aaa, bbb,cccc, dddd] [tree,human,animal,bird]
but i want to store this as
Cname Title
___________________________
aaa tree
bbb human
cccc animal
ddd bird
how do i do this???pls help to solve in this.
You'll have to insert/update the list values, actually you're inserting the string representations of the entire lists..
Assuming, both lists do exist (not null) and have the same length, then this is a trivial solution:
for (int i = 0; i < Cname.size(); i++ {
statement1.executeUpdate("INSERT INTO dbo.company (Cname,Title) SELECT
'"+Cname.get(i)+"','"+Title.get(i)+"'");
}
Note - every java class has an implementation of the toString() method, and that method is called, when you "use an object as a string", like in the expression to create the SQL statement. For lists, the method returns a String that simply includes the (String-representations of) the list element in brackets.
Put a for loop around your insert statement:
for(int i = 0; i < Cname.size(); i++)
statement1.executeUpdate("INSERT INTO dbo.company (Cname,Title) values ( '"+Cname.get(i)+"','"+Title.get(i)+"')");
If your db is SQL Server, you can reference the followng Q & A. Just prepare xml data and pass to Stored Procedure.
How to Update SQL Server Table With Data From Other Source (DataTable)
You can create a single SQL statement of this form:
INSERT INTO dbo.company (Cname, Title)
VALUES ('aaa', 'tree'),
('bbb', 'human'),
('cccc', 'animal'),
('dddd', 'bird')
With JDBC:
StringBuilder sql = new StringBuilder();
sql.append("INSERT INTO dbo.company (Cname,Title) VALUES ");
String glue = "";
for (int i = 0; i < Cname.size(); i++) {
sql.append(glue);
sql.append("('");
sql.append(Cname.get(i).toString().replace("'", "''"));
sql.append("', '");
sql.append(Title.get(i).toString().replace("'", "''"));
sql.append("')");
glue = ", ";
}
statement1.executeUpdate(sql.toString());
An alternative syntax (if the above doesn't work for Excel spreadsheets) is this:
INSERT INTO dbo.company (Cname, Title)
SELECT 'aaa', 'tree' UNION ALL
SELECT 'bbb', 'human' UNION ALL
SELECT 'cccc', 'animal' UNION ALL
SELECT 'dddd', 'bird'
Or with JDBC
StringBuilder sql = new StringBuilder();
sql.append("INSERT INTO dbo.company (Cname,Title) ");
String glue = "";
for (int i = 0; i < Cname.size(); i++) {
sql.append(glue);
sql.append("SELECT '");
sql.append(Cname.get(i).toString().replace("'", "''"));
sql.append("', '");
sql.append(Title.get(i).toString().replace("'", "''"));
sql.append("'");
glue = " UNION ALL ";
}
statement1.executeUpdate(sql.toString());

Categories