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.
Related
I am using jdbc to retrieve data from database. I have four different queries for that, however, the result of first query is used to get the data of second and fourth query. But, the resultset, gets updated as i run other queries. So is there any way that i can keep the resultset and add new results in it.
Here is my code:
class GetData{
String toDate;
String fromDate;
GetData(String d1,String d2) throws ClassNotFoundException, SQLException, ParseException, TransformerException, ParserConfigurationException {
toDate=d1;
fromDate=d2;
Connection connection= null;
ResultSet resultset= null;
String customerquery="SELECT o.ordernumber,o.orderdate,o.customernumber,c.customername,c.addressLine1,c.postalCode,c.city,c.country from orders o join customers c on o.customernumber=c.customernumber where orderdate between ? and ?";
String orderdetailquery="SELECT orderNumber,productCode,quantityOrdered,priceEach,orderLineNumber,(quantityOrdered * priceEach) as total FROM orderdetails where ordernumber=?";
String productsquery="SELECT productName,productLine,productVendor FROM products where productcode=?";
String employeequery="SELECT c.salesRepEmployeeNumber,e.firstname,e.lastname,o.officecode,o.city from customers c join employees e on c.salesRepEmployeeNumber = e.employeeNumber join offices o on e.officecode=o.officecode where c.customernumber=?";
Class.forName("com.mysql.cj.jdbc.Driver");
connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/classicmodels","root","root");
if(d1!=null || d2!=null) {
PreparedStatement p1= connection.prepareStatement(customerquery);
p1.setString(1, toDate);
p1.setString(2,fromDate);
resultset= p1.executeQuery();
PreparedStatement p2= connection.prepareStatement(orderdetailquery);
while(resultset.next()) {
p2.setString(1, resultset.getString("orderNumber"));
}
resultset=p2.executeQuery();
PreparedStatement p3= connection.prepareStatement(productsquery);
while (resultset.next()) {
p3.setString(1, resultset.getString("productcode"));
}
resultset=p3.executeQuery();
PreparedStatement p4=connection.prepareStatement(employeequery);
while(resultset.next()) {
p4.setString(1, resultset.getString("customernumber"));
}
resultset=p4.executeQuery();
resultset.close();
connection.close();
}
}
I am trying to use the result of first query that contains the column customernumber to fetch the data. While, executing the code a error comes that customernumber column not found. So, how can I use the result of first query in other queries. Also, i am trying to get all the result of queries in one resultset as I am trying to create a xml out of it by using DOM.
You can put everything in a single query. using joins.
select o.ordernumber,o.orderdate
, o.customernumber,c.customername
, c.addressLine1,c.postalCode,c.city,c.country
, t1.productCode, t1.quantityOrdered, t1.priceEach, t1.orderLineNumber,(t1.quantityOrdered * t1. priceEach) as total
, t2.productName, t2.productLine, t2.productVendor
, c.salesRepEmployeeNumber,t4.firstname,t4.lastname,t3.officecode,t3.city
from orders o
join customers c on o.customernumber=c.customernumber
left join orderdetails t1 on t1.orderNumber = o.orderNumber
left join products t2 on t2.productCode = t1.productCode
left join offices t3 on t3.offiecode = c.customernumber
left join employees t4 on t3.officecode = t4.officecode
ResultSet is getting changed because you are using the same reference (object) every time you are executing the sql statement, hence it is overriding the old result, so if you want to deal with previously returned ResultSet, you can create new ResultSet instance to use, and also you can create a Bean class to set the elements and make it List type to keep on adding the results as per your logic.
Create a POJO to store required properties retrieved from different queries.
The resultset is getting updated because the same reference variable is being used to assign the resultset of subsequent queries.
If you want to use the same variable, you can follow like this -
create a POJO (which can be used to create a xml out of it by using DOM).
get result of first query in resultset.
populate relevant properties of POJO from this resultset.
re-use the resultset to store result of next queries.
When you need to use previous results, get them from the POJO to be used as parameters in subsequent queries.
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.
Is there way to create sql query on the fly with MyBatis? To concretize: I have a query, where part of it (but not parameter) needs to be created in the runtime:
with dummy (id) as (
values (#{rangeEnd}) union all
select id - 1 from dummy where id - 1 >= #{rangeStart}
).......
The second part can be used as parameter, but, when trying the query as it is I get an exception:
[SQL0584] NULL or parameter marker in VALUES not allowed.
With plain JDBC I use MessageFormat:
PreparedStatement ps = connection.prepareStatement(
MessageFormat.format(MY_QUERY, currentRange.getRangeEnd()))
, but I haven't found a way how to do it with MyBatis.
It's really easy (answer from Dynamic Select SQL statements with MyBatis):
with dummy (id) as (
values (${rangeEnd}) union all
select id - 1 from dummy where id - 1 >= #{rangeStart}
).......
Use #SelectProvider annotation:
public interface SqlMapper {
static class PureSqlProvider {
public String sql(String sql) {
// Create your query here
return sql;
}
}
#SelectProvider(type = PureSqlProvider.class, method = "sql")
public List<Dummy> select(String sql);
}
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
i have two tables "Table1" with columns user_name,Password and course ID and another table "course" with columns course_id,course_name.I have used the following code to display the course ID from Table1 according to the user_name received from the login page.using ResultSet rs1.now i want to retrieve the course_name from the table "course" according to the course ID receieve from "Table1".for that in the second query pstmt2.setString(1, ); what parameter i should use to get the course_id value from the previous query
HttpSession sess=request.getSession();
String a=(String)sess.getAttribute("user");
String b=(String)sess.getAttribute("pass");
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection con=DriverManager.getConnection("jdbc:odbc:ggg");
Statement st = con.createStatement();
String query="select * from Table1 where user_name=?";
PreparedStatement pstmt=con.prepareStatement(query);
pstmt.setString(1,a);
ResultSet rs1=pstmt.executeQuery();
while(rs1.next())
out.println("<h3>COURSE ID: "+rs1.getString("course ID")+"<h3>");
String query2="SELECT * from course where course_id=?";
PreparedStatement pstmt2=con.prepareStatement(query2);
pstmt2.setString(1,);
ResultSet rs2=pstmt2.executeQuery();
while(rs2.next())
{
out.println("<h3>course name: "+rs2.getString("course_name")+"<h3>");
}
why do you go for two turns of database hit, even though you created one time connection object.
modify the query as below
SELECT * from course where course_id = (select course_id from Table1 where user_name=?);
from this query you noneed to give input of courseid also.
No need to hit database twice to get the results that you need. use the query
Select table1.course_id, course.course_name from table1, course where table1.course_id=course_id and table1.user_name=?
This should set the course_id parameter:
pstmt2.setString(1,rs1.getString("course_id"));
Or, as I see the "course_id" column may have a different name in "Table1":
pstmt2.setString(1,rs1.getString("course ID"));
As the other post mentioned there's no need to go to another set of query. Try this example query:
SELECT course.course_id, course.course_name
FROM table1 t1
INNER JOIN course c
ON t1.course_id = c.course_id
WHERE t1.user_name = ?;
Now if you insist your coding the parameter o your pstmt2.setString(1,); is:
pstmt2.setString(1,rs1.getString("course_id")); //or course ID defending on your column name