java how retrieve data from database - java

I have code
public static String getData(String query) {
String output = "";
try {
String connectionUrl = "jdbc:sqlserver://localhost:1234;databaseName=123;user=123;password=123";
Connection con = null;
Statement stmt = null;
ResultSet rs = null;
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
con = DriverManager.getConnection(connectionUrl);
String SQL = "select smth from tableName where smth";
stmt = con.createStatement();
rs = stmt.executeQuery(query);
while (rs.next()) {
output = (String) rs.getObject(1);
}
rs.close();
}
catch (Exception e) {
return "ERROR while retrieving data: " + e.getMessage();
}
return output;
}
It works if value is string. But if it integer? Or boolean? How to modify this method so it would be universal, no matter what type data I get I still return it as string?

First retreive the result in ResultSet rs,
then you can write the code like below.
You can check the instance of the object and than assign the value.
String str;
Object obj = (Object)rs.getObject(1);
if(obj instanceof String){
//do you work here for string like below
str=(String)obj;
}
else if (obj instanceof Integer){
//do your work for Integer
}
// same you can do for other types

in this line
output = (String) rs.getObject(1);
if string then use
output = rs.getString(1);
if int
output = rs.getInt(1);
click oracle for more info

You can't accurately do that without using ResultSetMetaData class to get the column type.
Get the column data according to the type of the column.

You are getting the value from the resultset presuming that it is always a String and trying to typecast the Object instance. You should make use of the retrieve methods based on the type. Most of the cases, we will be knowing the datatype of the column values from which we retried the data. You can write the program based on the column's type. that's why ResultSet API has a method for each datatype.
For String
rs.getString(1);
For Int
rs.getInt(1)
Please read the documentation of ResultSet

while (rs.next())
{
String[] data;
data = new String[100];
data[i] = rs.getString("smth");
i = i + 1;
}
Try this you got your data in array.. use array instead of object.

what about toString()?
while (rs.next()) {
output = rs.getObject(1).toString();
}

Related

Retrieve array of xml from PostgreSQL in Java

In order to retrieve a sample which has an XML field, I use the following code:
String my_call = "CALL my_proc(?)";
PreparedStatement ps = connection.prepareStatement(my_call);
ps.setSQLXML(1, null);
ResultSet rs = ps.executeQuery();
rs.next()
SQLXML desc = rs.getSQLXML(1);
// use desc
And this works perfectly.
But another procedure returns an array of XML. I tried the following code, without success:
String my_call = "CALL my_other_proc(?)";
Array xml = connection.createArrayOf("xml", new Object[]{}); // what's wrong here ?
PreparedStatement ps = connection.prepareStatement(my_call);
ps.setArray(1, xml);
ResultSet rs = ps.executeQuery();
rs.next();
Array xml_array = rs.getArray(1);
SQLXML[] sqlxmls = (SQLXML[])xml_array.getArray(); // what's wrong here ?
I get the following error:
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.sql.SQLXML;
For arrays, custom types other than UUID (via ArrayAssistant) and JSONB (returned as String) is currently not supported.
However, you work around that using String, e.g.:
Array xml_array = rs.getArray(1);
Object[] sqlxmls = (Object[]) xml_array.getArray();
for (Object o : sqlxmls) {
PGobject pgValue = PGobject.class.cast(o);
SQLXML xml = conn.createSQLXML();
xml.setString(pgValue.getValue());
StreamSource source = xml.getSource(StreamSource.class);
// ...
}
For further details, have a look at the code of PgArray.buildArray(...).
This also applies to statement parameters. Instead of using the standard JDBC SQLXML objects, just use a String[] as the argument, e.g.:
List<String> docs = new ArrayList<>();
for (int i = 0; i < 5; i++) {
docs.add("<test index=\"" + (i + 1) + "\"><property value=\"true\"/></test>");
}
Array docsArray = conn.createArrayOf("XML", docs.toArray());
try (PreparedStatement stmt = conn.prepareStatement("INSERT INTO t_array_xml (id, docs) VALUES (?, ?);")) {
stmt.setInt(1, 1);
stmt.setArray(2, docsArray);
stmt.executeUpdate();
}
docsArray.free();

Query data and pass as input for another function in a loop Java

I am writing an application that required to query data from oracle database and send each queried data as input to another function in java. I am not sure how to pass those queried data as input to another function. I am trying to use Arraylist but still could not able to pass as input. Any help will be appreciated. Hope to hear from you all.
String dbuserName = "";
String dbpassword = "";
String url = "jdbc:oracle:thin:#//xxxxxxxxxxxxxx";
String driverName = "oracle.jdbc.driver.OracleDriver";
Connection conn = null;
Session session = null;
try{
// Some Connection code to database here before below code
Statement stmt = conn.createStatement();
ResultSet rs = stat.executeQuery( "SELECT ..." );
ArrayList <String[]> result = new ArrayList<String[]>();
/*Queried data has only one column, that is useid, now need to
send each id as input to below try/catch statement*/
try {
userManager.enable(USER_LOGIN, true);
System.out.print("\n Enabled user Successfully");
} catch (ValidationFailedException e) {
e.printStackTrace();
logger.severe("ValidationFailedException: " + e ");
}
This will help you
while (rs.next()) {
int i = 1;
result.add(rs.getString(i++));
}
Then in the for loop
for(int i=0;i<result.size()-1;i++)
{
String USER_LOGIN=result.get(i);
userManager.enable(USER_LOGIN, true);
}

Cant get expected result

This is coding I needed to implement in my project when I am calling method getClassId() in my servlet it returns one and first value from the table however table contains many records.When I use System.out.println(rs.getString(clId)) ; in getClassId() method it displays correct output. Simply I can Say it does not iterate only once through rs.getString() when I call getClassName() in getClassId().
public List<String> getClassId() {
Statement stmt = null;
List<String> stList = new ArrayList<String>();
try {
Con = conManager.getConnection();
stmt = Con.createStatement();
String query = "SELECT * FROM classes";
rs=stmt.executeQuery(query);
while(rs.next()) {
stList = getClassName(rs.getString(clId));
}
} catch(Exception e) {
System.out.println(e);
}
return stList;
}
public String getClassName(String id) {
String str = "";
Statement stmt = null;
try {
Con = conManager.getConnection();
stmt = Con.createStatement();
String query = "SELECT * FROM classes where clId="+id;
rs=stmt.executeQuery(query);
while(rs.next()) {
str = rs.getString("className");
}
} catch(Exception e) {
System.out.println(e);
}
return str;
}
The getClassName() method here returns the className value in the last row found in the database resultset as :
while(rs.next()){
str = rs.getString("className");
}
Clearly str contains the last value in the resultset.
Now getClassId() method invokes getClassName() by iteratively passing the values of clId but in the getClassId() method, you are reassigning the value to stList as given below [even this should fail at the time of compilation as String value cannot be assigned to a List datatype..Please check]:
while(rs.next() ){
stList = getClassName(rs.getString(clId));
}
Instead try using the below code :
while(rs.next()){
stList.add(getClassName(rs.getString(clId)));
}
This will add all the values returned by getclassName() to the arrayList.
Hope that helps..

Problem using generics in function

I have this functions and need to make it one function. The only difference is type of input variable sourceColumnValue. This variable can be String or Integer but the return value of function must be always Integer.
I know I need to use Generics but can't do it.
public Integer selectReturnInt(String tableName, String sourceColumnName, String sourceColumnValue, String targetColumnName) {
Integer returned = null;
String query = "SELECT "+targetColumnName+" FROM "+tableName+" WHERE "+sourceColumnName+"='"+sourceColumnValue+"' LIMIT 1";
try {
Connection connection = ConnectionManager.getInstance().open();
java.sql.Statement statement = connection.createStatement();
statement.execute(query.toString());
ResultSet rs = statement.getResultSet();
while(rs.next()){
returned = rs.getInt(targetColumnName);
}
rs.close();
statement.close();
ConnectionManager.getInstance().close(connection);
} catch (SQLException e) {
System.out.println("Заявката не може да бъде изпълнена!");
System.out.println(e);
}
return returned;
}
// SELECT (RETURN INTEGER)
public Integer selectIntReturnInt(String tableName, String sourceColumnName, Integer sourceColumnValue, String targetColumnName) {
Integer returned = null;
String query = "SELECT "+targetColumnName+" FROM "+tableName+" WHERE "+sourceColumnName+"='"+sourceColumnValue+"' LIMIT 1";
try {
Connection connection = ConnectionManager.getInstance().open();
java.sql.Statement statement = connection.createStatement();
statement.execute(query.toString());
ResultSet rs = statement.getResultSet();
while(rs.next()){
returned = rs.getInt(targetColumnName);
}
rs.close();
statement.close();
ConnectionManager.getInstance().close(connection);
} catch (SQLException e) {
System.out.println("Заявката не може да бъде изпълнена!");
System.out.println(e);
}
return returned;
}
No you don't need to use generics for this.. generic should be used when your supported Types can be to many and you don't know about them before hand and they share something common in them.
Only for just two Types Generics is not a good choice. Using objects can be a better choice.
May be i will say you don't even need to merge these functions, that's what polymorphism is for. keeping things discreet will allow more readability of code
No need to use generic, you can just use Object as the variable type for the function :
public Integer selectIntReturnInt(String tableName, String sourceColumnName, Object sourceColumnValue, String targetColumnName) {
Integer returned = null;
String query = "SELECT "+targetColumnName+" FROM "+tableName+" WHERE "+sourceColumnName+"='"+sourceColumnValue.toString()+"' LIMIT 1";
try {
Connection connection = ConnectionManager.getInstance().open();
java.sql.Statement statement = connection.createStatement();
statement.execute(query.toString());
ResultSet rs = statement.getResultSet();
while(rs.next()){
returned = rs.getInt(targetColumnName);
}
rs.close();
statement.close();
ConnectionManager.getInstance().close(connection);
} catch (SQLException e) {
System.out.println("Заявката не може да бъде изпълнена!");
System.out.println(e);
}
return returned;
}
You don't need to use generics. Just declare it as
public Integer selectReturnInt(String tableName,
String sourceColumnName,
Object sourceColumnValue,
String targetColumnName) {
...
}
For the love $deity please don't use dynamic SQL. You will get injection vulnerabilities.
You want to break this into (at least) three method. One with the bulk of the implementation, and one each for the different types.
Also of note:
Resource handling should be of the form final Resource resource = acquire(); try { ... } finally { resource.release(); }, or in JDK7 try (final Resource resource = acquire()) { ... }.
Singletons are the work of the devil.
Exception handling considered a good idea, whereas sinking to a printf is bad.
You're probably better off only returning a value if there is exactly one result set and throwing an exception otherwise.
Have the second method just call the first:
public Integer selectIntReturnInt(String tableName, String sourceColumnName, Integer sourceColumnValue, String targetColumnName) {
return selectReturnInt(tableName, sourceColumnName, sourceColumnValue.toString(), targetColumnName);
}

Using PreparedStatement template issue

Here's my static utility:
//String sqlQuery = "select count(name) as num from tbname where name = ?"
//String name = "testString";
private static int correct(Connection connection, String sqlQuery, String name) {
int result = 0;
PreparedStatement statatement = null;
ResultSet rs = null;
try {
statatement = connection.prepareStatement(sqlQuery);
statatement.setString(1, name);
rs = statatement.executeQuery();
while (rs.next()) {
result = rs.getInt("num");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
rs.close();
statatement.close();
} catch (SQLException e) {
throw new RuntimeException(e.getMessage());
}
return result;
}
}
The method above returns 0 (incorrect result), but the following one returns '1' (it works OK, it the same sql query):
//String sqlQuery = "select count(name) as num from tbname where name = 'testString'"
private static int correct(Connection connection, String sqlQuery, String name) {
int result = 0;
PreparedStatement statatement = null;
ResultSet rs = null;
try {
statatement = connection.prepareStatement(sqlQuery);
rs = statatement.executeQuery();
while (rs.next()) {
result = rs.getInt("num");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
rs.close();
statatement.close();
} catch (SQLException e) {
throw new RuntimeException(e.getMessage());
}
return result;
}
}
Could you please give me any advise, so I could resolve the problem.
PS: I'm not sure if it does matter, but the actual streetName - has a name in windows-1251 encoding (Russian) text.
PPS: The database is Oracle 10.
It might be a character set issue. According to the Oracle JDBC Drivers release 10.1.0.2.0 (10g) README:
The following is a list of known
problems/limitations:
If the database character set is AL32UTF8, you may see errors under the
following circumstances:
accessing LONG and VARCHAR2 datatypes.
binding data with setString() and setCharacterStream().
So if your database character set is AL32UTF8, you might have to get it changed to something else.
Also, what is the datatype of your column? VARCHAR2?
It seems the encoding conflict with the one which you set in your DB encoding charset and the the String you are passing..
You can do these 2 tries
Set the DB encoding to UTF-8 and then give a try. If this does not work you may go with following 2nd option
Set DB encoding charset to UTF-8 and also set the String by using this String constructor String(byte[] bytes, String charsetName)

Categories