My iOS app needs to communicate with the server database. I choose Oracle 11g/ Oracle SQL developer for server database implementation. I recently learned myself about JDBC, JAVA and SQL queries. Hence my question may seem lame.
Here is my situation:
My database contains two tables (T1 and T2). I can send data to the server and store it in the database via my iOS app. Now I need to retrieve the data from the server as per app's request. For this purpose, I use a ResultSet variable as:
private ResultSet rs = SQLProcess("SELECT * FROM T1, T2");
Here, SQLprocess is a public method for executeQuery with return type Resultset and arguments as the columns of the two tables.The sql query for the executeQuery is as follows:
"SELECT a.ID '"+msg1+"', a.X '"+msg2+"', a.Y '"+msg3+"', a.Xe '"+msg4+"', a.Ye '"+msg5+"', a.SDe '"+msg6+"', a.Xs '"+msg7+"', a.Ys '"+msg8+"', a.SDs '"+msg9+"', a.Xw '"+msg10+"', a.Yw '"+msg11+"', a.SDw '"+msg12+"', a.Xn '"+msg13+"', a.Yn '"+msg14+"', a.SDn '"+msg15+"', b.ID '"+msg16+"', b.Zn '"+msg17+"' FROM T1 a , T2 b WHERE a.ID = b.ID");
Here, msg1 to msg17 are the arguments of the method SQLProcess (which are the columns of the two tables. msg1 to msg15 represent columns of T1 and msg16 and msg17 represent columns of T2).
The method that is responsible to send data to the client (iOS app) is given as follows:
void sendTo(InetAddress add) {
try{
DataOutputStream out = (DataOutputStream) clients.get(add);
while(rs.next()){
String msg = '\n' +rs.getString(1) + "," + rs.getString(2)+ "," + rs.getString(3)+ "," + rs.getString(4)+ "," + rs.getString(5)+ "," + rs.getString(6)+ "," + rs.getString(7)+ "," + rs.getString(8) +"," + rs.getString(9)+ "," + rs.getString(10)+ "," + rs.getString(11)+ "," + rs.getString(12)+ "," + rs.getString(13)+ "," + rs.getString(14)+ "," + rs.getString(15)+ "," + rs.getString(16)+ "," + rs.getString(17)+'\n';
System.out.println(msg);
out.writeUTF(msg);
}
}catch(IOException e){
e.printStackTrace();
}catch (SQLException e) {
e.printStackTrace();
}
}
With this method, data are sent to the iOS app but with mixed ways. i.e If there are two rows in each table:
T1:
Row1: 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
Row2: 2,2,3,4,5,6,7,8,9,10,11,12,13,14,15
T2:
Row1: 1,16
Row2: 2,17
Then the data received at the iOS app is:
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,1,16
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,2,17
2,2,3,4,5,6,7,8,9,10,11,12,13,14,15,1,16
2,2,3,4,5,6,7,8,9,10,11,12,13,14,15,2,17
What I need is:
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,1,16 and 2,2,3,4,5,6,7,8,9,10,11,12,13,14,15,2,17.
I think that the cursor is moved to both the tables (while(rs.next())). Is there any way to move the cursor across rows of only one table among many tables? Or is there any other best solution for my problem?
Sorry for the lengthy post. Thank you in advance.
Got the solution. :)
There were two 'errors' in my code:
1) I wanted to have an inner join but did cross join query. Thanks #krokodilko for the prompt comment.
2) I'm not supposed to use column name with small and capital letters together (seems invalid operation). I changed all the small characters to capital.
The new sql query is:
("SELECT T1.ID, T1.X, T1.Y , T1.XE , T1.YE , T1.SDE , T1.XS , T1.YS , T1.SDS , T1.XW , T1.YW , T1.SDW , T1.XN , T1.YN , T1.SDN , T2.ID , T2.ZN FROM T1 , T2 WHERE T1.ID = T2.ID")
I just coded this way:
Cursor cursor;
String sql = "SELECT l.acao, SUM(strftime('%s',l.data_fim) - strftime('%s',l.data_inicio)) AS total_time," +
"FROM logs AS l " +
"WHERE l.data_fim IS NOT NULL " +
"GROUP BY l.acao";
I need to sum the seconds between two dates and I named this sum total_time. But when I try to get the result of total_time it always returns null, see next code:
String totalTimeInSeconds = (String) cursor.getString(cursor.getColumnIndex("total_time"));
When I put this same query in SqlLiteStudio it works perfectly. What am I doing wrong?
Your problem is that the value in the cursor actually is NULL.
This can happen only when the original date values are not in one of the supported date formats. You have to change your database.
instead of using cursor.getColumnIndex(), you can enter the exact index in it. In your case the total_time index is 1. Ex : cursor.getString(1) or cursor.getInt(1)
I am using Spring 3.1.1 with Hibernate 4 and a MSSQL database. Finally, I have been able to query my database with joins in my table that returns the correct answers. Although, it seems that it does not return the entire strings of my messages, but cuts at 29/30 digits. Here is my query:
SQLQuery sql = this.getCurrentSession().createSQLQuery(
"SELECT event.id as eventid, CAST(event_type.type_name AS varchar) as eventtype, event.check_date, event.event_date, event.status, CAST(event_message.message AS varchar) as eventmessage " +
"FROM event_log event " +
"LEFT JOIN event_type " +
"ON (event.event_type_id = event_type.id) " +
"LEFT JOIN event_message " +
"ON (event.event_message_id = event_message.id) " +
"WHERE event.event_type_id = " + jobId +
"ORDER BY eventid");
The result can be:
4506 Database 2014-01-15 14:14:15.02 2014-01-15 14:14:15.02 false Database-connection cannot be
Where the columns are id, task_name, check_date, event_date, status and the message-string at the end. .
The result goes to a ArrayList<Object[]> where I read row[0] etc. to get the entities in the row. The string message gets cut after 29 digits, which is disturbing. Why does it cut the string and how can I fix this? In my database the string exists in it's full and is entitled 400 characters max.
I know this is probably not the best way to query my database, but it will do for my application since it works.
You are using varchar without a length. Never do this!
Replace:
CAST(event_type.type_name AS varchar)
With something like:
CAST(event_type.type_name AS varchar(255))
In some contexts, the default length is 32. In some it is 1. In general, though, always specify the length.
EDIT:
Actually, you probably don't even need the cast. Why not just have event_type.type_name in the select list?
I understand how to do this on paper in SQL, but am having trouble implementing this in Java (this is the first time I am actually programming JDBC stuff)
For example, say my database consists of:
movie(code, title, publisher)
customer(custno, name)
borrowed(custno, code)
And I want to find the name of customers who borrowed every movie by pubisher ABC
string no_of_ABC_movies = "SELECT COUNT(publisher), publisher FROM movie, WHERE movie.publisher = 'ABC'";
string no_of_cust_ABC_movies = "SELECT COUNT(name), name FROM customer, borrowed, movie, WHERE customer.custno = borrowed.custno AND borrowed.code = movie.code AND movie.publisher = 'ABC'";
String query = "SELECT name" +
" name FROM customer, borrowed, movie" +
" WHERE customer.custno = borrowed.custno AND" +
" borrowed.code = movie.code AND" +
" movie.publisher = 'ABC' AND" + " "
no_of_cust_ABC_movies + " = " + no_of_ABC_movies;
This isn't the exact database I am working with, but query will work and print out the names of people who borrowed movies from ABC without the last line, but says I have an error in SQL syntax with the last line so I guess I don't know how to use one query within another.
It depends on your DBMS, but every SQL variant I've seen requires parens around subqueries.
Try something like:
...
" movie.publisher = 'ABC' AND ("
no_of_cust_ABC_movies + ") = (" + no_of_ABC_movies + ")";
You have problem with double name field without being separated by a comma in your query.
If your code is exactly as listed above, you have compilation error just above the last line-missing + to concatenate strings.
If that's a typo below is my suggestion.
Remove duplicate select (use only one name) or
Separate names by a comma ( I don't see a point of selecting name twice though)
And your last line is wrong.. you can not compare two select queries that way.. Just add the required where clauses.
(You should read database joins first, and then solve your problem)
I like to get my queries working in the query browser or workbench, then copy them over to Java. It keeps it to one new thing at a time...
You're query actually starts with
SELECT name name FROM customer ...
The name column is duplicated - maybe that the problem.