I am getting ResultSet after an Oracle query. when I iterating through the ResultSet its going in infinite loop.
ResultSet rs = (ResultSet) // getting from statement
while (rs.next()) {
//
//
}
this loop is not terminating so I tried finding number of records using rs.getFetchSize() and its returning a value 10.
I want to know if this is the correct method to find out number of records in ResultSet and if the count is 10 why is it going in infinite loop.
Please give your opinion.
Actually, the ResultSet doesn't have a clue about the real number of rows it will return.
In fact, using a hierachical query or a pipelined function, the number might as well be infinite. 10 is the suggested number of rows that the resultset should/will try to fetch in a single operation. (see comment below).
It's best to check your query, if it returns more rows than you expect.
To know number of records present, try the following code
ResultSet rs = // getting from statement
try {
boolean b = rs.last();
int numberOfRecords = 0;
if(b){
numberOfRecords = rs.getRow();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
A simple getRowCount method can look like this :
private int getRowCount(ResultSet resultSet) {
if (resultSet == null) {
return 0;
}
try {
resultSet.last();
return resultSet.getRow();
} catch (SQLException exp) {
exp.printStackTrace();
} finally {
try {
resultSet.beforeFirst();
} catch (SQLException exp) {
exp.printStackTrace();
}
}
return 0;
}
Your resultSet should be scrollable to use this method.
Just looked this seems to be on similar lines on this question
When you execute a query and get a ResultSet, I would say it is really at this moment you or even the program-self actually don't how many results will be returned, this case is very similar Oracle CURSOR, it is just declare to Oracle that you want do such a query, hence then we have to for each ResultSet to get row one by one up to the last one.
As the above guys has ready answered: rs.last will iterate to last one at this time the program has ability to totally how many rows will be returned.
if(res.getRow()>0)
{
// Data present in resultset<br>
}
else
{
//Data not present in resultset<br>
}
You can look at snippet of code below where you can find how to calculate the loaded number of records from data set. This example is working with external data set (whiich comes in json format) so you can start with yours. The necessary piece of code is placed in script of controller (this page is based on ApPML javascript and cotroller works with loaded objects of ApPML). Code in controller returns number of the loaded reocords of data set and number of fields of data model.
<!DOCTYPE html>
<html lang="en-US">
<title>Customers</title>
<style>
body {font: 14px Verdana, sans-serif;}
h1 { color: #996600; }
table { width: 100%;border-collapse: collapse; }
th, td { border: 1px solid grey;padding: 5px;text-align: left; }
table tr:nth-child(odd) {background-color: #f1f1f1;}
</style>
<script src="http://www.w3schools.com/appml/2.0.2/appml.js"></script>
<body>
<div appml-data="http://www.w3schools.com/appml/customers.aspx" appml-controller="LukController">
<h1>Customers</h1>
<p></p>
<b>It was loaded {{totalRec}} records in total.</b>
<p></p>
<table>
<tr>
<th>Customer</th>
<th>City</th>
<th>Country</th>
</tr>
<tr appml-repeat="records">
<td>{{CustomerName}}</td>
<td>{{City}}</td>
<td>{{Country}}</td>
</tr>
</table>
</div>
<script>
function LukController($appml) {
if ($appml.message == "loaded") {
$appml.totalRec = Object.keys($appml.data.records).length;
}
}
// *****************************************************************
// Message Description
//
// ready Sent after AppML is initiated, and ready to load data.
// loaded Sent after AppML is fully loaded, ready to display data.
// display Sent before AppML displays a data item.
// done Sent after AppML is done (finished displaying).
// submit Sent before AppML submits data.
// error Sent after AppML has encountered an error.
// *****************************************************************
</script>
</body>
</html>
I got answer:- The below are steps that you need to follow:
Make sure your are using select query(e.g select * from employee).
Don't use count query(e.g select count(*) from employee).
Then use below steps:
Statement stmt=conn.createStatement();
ResultSet rs=stmt.executeQuery("select * from employee");
while(rs.next()){
rowCount++;
}
return rowCount;
}
where rs is object of ResultSet.
Then you will get exact number of row count.
Related
I have worked on saving a single file into database(postgresql) and it works fine. But I am stuck when i try to upload multiple files.
My jsp fileupload :
<input type="file" id="reqFile" name="attachments.myFile" multiple/>
This is my action method :
public String SaveAttachments() throws SQLException, IOException {
int case_id = (Integer) session.get("case_id");
System.out.println("in save attachments()");
int uploaded_by = 1;
try {
File destFile = new File(attachments.getMyFileFileName());
FileUtils.copyFile(attachments.getMyFile(), destFile);
fis = new FileInputStream(destFile);
currentCon = ConnectionManager.getConnection();
pstmt = (PreparedStatement) currentCon.prepareStatement("insert into case_attachments(case_id, attachment, attachment_title, upload_date, uploaded_by) values(?,?,?,current_date,?)");
pstmt.setInt(1, case_id);
pstmt.setBinaryStream(2, fis, (int) destFile.length());
pstmt.setString(3, attachments.getMyFileFileName());
pstmt.setInt(4, uploaded_by);
pstmt.executeUpdate();
} catch (Exception e) {
System.out.println("Error From SaveAttachments :" + e);
}
return SUCCESS;
}
When I attach multiple files it goes into the same column in database in comma seperated format. How can i save files in different rows when the user attaches multiple files?
Thanks In advance.
You can upload multiple files like described here, then you simply need to loop them and insert them in the database one at time.
You just need to decide if using a business layer or doing the insert job directly from the Action (not the best practice...), and if putting all the files in a single transaction or each one in its own.
Remember that HTML5 multiple attribute should be multiple="multiple", not just multiple (although the majority of the browsers handles it right even when "quirk").
use array for multiple uploading.
<td><input type="file" name="file[]" class="multi" id="reqFile"></td>
i have a resultset. if result set is empty or null, then i want to set the value of "int b=0" in str16. And if the result set is not empty/find out something then execute the query. But i am facing some problem when the resultset is empty, then value is not setting in str16. What i did in my project is that after login i will show the total number of leave on employee profile if he took leave already. if employee did not take any leave then show 0 on the profile.
*checkleave.jsp *
<%# page import="java.sql.*" %>
<%# page import="java.io.*" %>
<%
// storing the login id in abc becouse i have give table name as employee id
String abc= session.getAttribute("empid").toString();
%>
<%
try{
int b=0;
Statement st=connection.createStatement();
ResultSet rs=st.executeQuery("select approcode,approemail,appromon,approvemon,approtue,approvetue,approwed,approvewed,approthr,approvethr,approfri,approvefri,approsat,approvesat,commen,months,SUM(nol) from `pushkalit`.`approval`WHERE (CONVERT( `approcode` USING utf8 ) LIKE '%"+abc+"%')");// here what i am doing that if employee login then check in approval table where is approcode column as employee id if find something then execute table if column is not there then put value of b(i have declared int b=0) in str16.
if(rs !=null)
{
if (rs.isBeforeFirst() && rs.isAfterLast())
{
session.setAttribute("str16",b);
}
else
{
while(rs.next())
{
String str=rs.getString("approcode");
String str1= rs.getString("approemail");
String str2=rs.getString("appromon");
String str3=rs.getString("approvemon");
String str4=rs.getString("approtue");
String str5=rs.getString("approvetue");
String str6=rs.getString("approwed");
String str7=rs.getString("approvewed");
String str8=rs.getString("approthr");
String str9=rs.getString("approvethr");
String str10=rs.getString("approfri");
String str11=rs.getString("approvefri");
String str12=rs.getString("approsat");
String str13=rs.getString("approvesat");
String str14=rs.getString("commen");
String str15=rs.getString("months");
String str16=rs.getString(17);
session.setAttribute("str16",str16);
}
}
}
else
{
session.setAttribute("str16",b);
}
}
catch(Exception e) {
System.out.println(e);
}
%>
but i am getting problem when employee login if column is empty then getting error. this is empprofile.jsp.it will come after login. this code i have put in empprofile.jsp
<%
String a = session.getAttribute("str16").toString();
int y = Integer.parseInt(a);
<tr><td><label>Total Leave Day:</label></td>
<td><%=y %></td>
%>
Methods like isBeforeFirst() and isAfterLast() are only required to work with scrollable result sets. If you want to be able to use all types of result sets and all JDBC implementations, then you have several options:
Define a boolean variable initially set to false, and set it to true in the while loop; base your decision on this while loop
Similar to one, but define an integer count instead
Check rs.next() and process the result using do ... while
I have a very peculiar problem. I am developing a web application in Java and Spring MVC. I have a row that can be duplicated dynamically by the user on the press of a button. Each row has around 10 fields. I am binding these rows as list of objects in the backing bean and initializing this list as a lazy list in the bean. Now, it has been working fine till now but the user tried to enter 12 rows and on the 12th row, i.e., the 11th iteration(the iteration starting from 0), the 5th field becomes empty, although the user enters values and all the other fields retain their values. Since the binding happens with name, I have checked the name of the field, it is consistent with the rest of the fields in the same row and the rest of the rows. I am unable to debug and rectify the issue. This is affecting the code in production.
I can provide whatever code snippets are required.
Can somebody please help me with this. Thanks in advance.
EDIT: I tried executing the same code on a different server and it works fine there but still persists on the live server. And the problem seems to be only in the 11th iteration's 5th field. Could it be a problem with the server
Adding code:
JSP:
<c:forEach items="${addProposal.requirements}" var="req" varStatus="status">
<!--Rest of the fields-->
<form:input path="requirements[${status.index}].sampleSize" id="r_sample${status.index}" value="${addProposal.requirements[status.index].maximumFeasibility}" class="inptform2" style="width:65px;" size="10" onchange="functions();"/>
<!--Rest of the fields-->
<td width="57" align="left" valign="middle" id="btn-close" class="btn-remove">' +
'<a href="javascript:void(0)"><img src="images/btncross.png" width="18" height="17" border="0" />' +
'</a>
</td>
</c:forEach>
Javascript:
$(document).ready(function(){
//Add more dynamic rows
$("#addMore").click(function() {
var tr_temp=$("#requirement tr:first").clone();
//rest of the fields code
tr_temp.find("#r_sample0").each(function() {
$(this).attr({
'id': function(_, id) { return 'r_sample' + i},
'name': function(_, name) { return 'requirements[' + i + '].sampleSize'},
'value': ''
});
}).end();
tr_temp.find("td:last").remove();
tr_temp.append(btn_close);
tr_temp.appendTo("#requirement");
i++;
});
//To remove a dynamically added row
$("#btn-close").live('click',function(){
doNotDel=false;
count=0;
//To fetch the values of the Input Fields
$(this).parent().find("input").each(function(){
count++;
var value = $(this).val();
var id=$(this).attr('id');
if(id.indexOf("r_total")==-1){
//Skip the minutes and currency column
if(id.indexOf("minutes")==-1 && id.indexOf("currencyValF")==-1 && id.indexOf("currencyVal")==-1){
if(value!=""){
doNotDel=true;
return false; //breaks the .each loop
}
}
}
});
if(doNotDel==false){
$(this).parent().remove();
}
});
});
Bean:
private List<RequirementBean> requirements;
//in constructor
requirements = LazyList.decorate(
new ArrayList<RequirementBean>()
, new InstantiateFactory(RequirementBean.class));
Controller:
#RequestMapping(value="/addProposal", method=RequestMethod.POST)
public String addProposal(#ModelAttribute("addProposal") ProposalBean proposal, ModelMap model){
RequirementBean req;
List<RequirementBean> reqmtList;
System.out.println("Before empty rows");
reqmtList = proposal.getRequirements();
for(int i=0; i<reqmtList.size(); i++){
req = reqmtList.get(i);
if(req.getCountry()!=null){
System.out.println("sample size " + i + " :" + req.getSampleSize());
}
}
}
EDIT:
I tried changing the value of the 4th row in the same column, and now the code seems to work. I am still not able to understand what is the issue.
Hope this gives more clarity. Please help me.
I am trying to store the results of my query in a string, and print them to the bottom of my JSP page by passing that string to it. Right now, the JSP page displays fine initially, but nothing is happening when I click the button to post the command. Earlier when I accessed the servlet from an html page, and printed all my output to out using a PrintWriter, I got the results to display, but they would display on a separate page.
1) Is it a good idea to store out in this way, or should I make it something different than a string?
2) How do I get the results of the query to post to the JSP page?
databaseServlet.java
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.sql.*;
#SuppressWarnings("serial")
public class databaseServlet extends HttpServlet {
private Connection conn;
private Statement statement;
public void init(ServletConfig config) throws ServletException {
try {
Class.forName(config.getInitParameter("databaseDriver"));
conn = DriverManager.getConnection(
config.getInitParameter("databaseName"),
config.getInitParameter("username"),
config.getInitParameter("password"));
statement = conn.createStatement();
}
catch (Exception e) {
e.printStackTrace();
}
}
protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String out = "\n";
String query = request.getParameter("query");
if (query.toString().toLowerCase().contains("select")) {
//SELECT Queries
try {
ResultSet resultSet = statement.executeQuery(query.toString());
ResultSetMetaData metaData = resultSet.getMetaData();
int numberOfColumns = metaData.getColumnCount();
for(int i = 1; i<= numberOfColumns; i++){
out.concat(metaData.getColumnName(i));
}
out.concat("\n");
while (resultSet.next()){
for (int i = 1; i <= numberOfColumns; i++){
out.concat((String) resultSet.getObject(i));
}
out.concat("\n");
}
}
catch (Exception f) {
f.printStackTrace();
}
}
else if (query.toString().toLowerCase().contains("delete") || query.toLowerCase().contains("insert")) {
//DELETE and INSERT commands
try {
conn.prepareStatement(query.toString()).executeUpdate(query.toString());
out = "\t\t Database has been updated!";
}
catch (Exception l){
l.printStackTrace();
}
}
else {
//Not a valid response
out = "\t\t Not a valid command or query!";
}
RequestDispatcher dispatcher = request.getRequestDispatcher("/dbServlet.jsp");
dispatcher.forward(request, response);
request.setAttribute("queryResults", out);
}
}
dbServlet.jsp
<?xml version = "1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- dbServlet.html -->
<html xmlns = "http://www.w3.org/1999/xhtml">
<head>
<title>MySQL Servlet</title>
<style type="text/css">
body{background-color: green;}
</style>
</head>
<body>
<h1>This is the MySQL Servlet</h1>
<form action = "/database/database" method = "post">
<p>
<label>Enter your query and click the button to invoke a MySQL Servlet
<textarea name = "query" cols="20" rows="5"></textarea>
<input type = "submit" value = "Run MySQL Servlet" />
<input type = "reset" value = "Clear Command" />
</label>
</p>
</form>
<hr>
<%=
request.getAttribute("queryResults");
%>
</body>
</html>
dispatcher.forward(request, response);
request.setAttribute("queryResults", out);
It should be like this
request.setAttribute("queryResults", out);
dispatcher.forward(request, response);
Before the request is dispatched the attributes has to be set
1) Is it a good idea to store out in this way, or should I make it something different than a string?
Since this is tabular data, I'd use something that preserves that structure, so that the JSP can piece it apart easily for customized formatting. Bold headers, putting it in an HTML table and stuff. Either some custom bean, or maybe just a List<String[]>.
2) How do I get the results of the query to post to the JSP page?
What you are doing now (request.setAttribute) should work. However, you need to set the attribute before you forward the request.
You could then print the String you now have like this:
<%= request.getAttribute("queryResults") %>
Or if you go with a table-structure
<% List<String[]> rows = request.getAttribute("queryResults"); %>
and then loop over that.
1) Is it a good idea to store out in this way, or should I make it something different than a string?
NO. Don't mix the presentation logic in Java code. Leaverage your JSP for that purpose I would advice you to use JAVA objects and store the row wise values in one object instance. Put all the objects in a collection and use the same in JSP for display. Same goes with column names.
2) How do I get the results of the query to post to the JSP page?
In your current format of queryResults, just print the results using = operator or out.println method in your JSP as:
<hr>
<%=request.getAttribute("queryResults"); %>
or
<% out.println(request.getAttribute("queryResults"));%>
But if you decide t use collection as adviced in answer1, then get the collection back from the request, iterate and print the results, e.g. if you decide to use List<String[]> where String[] maps one row data then:
<TABLE id="results">
<% List<String> columns = (List<String>)request.getAttribute("queryColumns");
List<String[]> results = (List<String[]>)request.getAttribute("queryResults");
out.println("<TR>");
for(String columnName: columns ){
out.println("<TD>"+columnName+"</TD>");
}
out.println("</TR>");
//print data
for(String[] rowData: results){
out.println("<TR>");
for(String data: rowData){
out.println("<TD>"+data+"</TD>");
}
out.println("</TR>");
}
%>
</TABLE>
I have the below code that search based on first name and last name. Once I press space after first name, then the search result disappears.How to make the search result appear after pressing space. I am calling the ajax function in a textbox for firstname/LastName.
<script type="text/javascript">
function lookup(inputString) {
if(inputString.length == 0) {
$('#suggestions').hide();
} else {
$.post("states.jsp", {queryString: ""+inputString+""}, function(data){
if(data.length >0) {
$('#suggestions').show();
$('#autoSuggestionsList').html(data);
}
});
}
}
function fill(thisValue) {
$('#inputString').val(thisValue);
setTimeout("$('#suggestions').hide();", 200);
}
</script>
// States.JSP File
String sql = "SELECT EMP_EMPLOYEE_ID, EMP_FNAME, EMP_LNAME FROM UAP.dbo.UAP_EMPLOYEE where EMP_FNAME LIKE '%"+name+"%' OR EMP_LNAME LIKE '%"+name+"%';";
Statement stm = con.createStatement();
stm.executeQuery(sql);
ResultSet rs= stm.getResultSet();
while (rs.next ()){
out.println("<li onclick='fill(\""+rs.getString("EMP_FNAME")+" " +rs.getString("EMP_LNAME")+"\");'>"+rs.getString("EMP_FNAME")+" "+rs.getString("EMP_LNAME")+" </li>");
}}catch(Exception e){
out.println("Exception is ;"+e);
}
The variable name in your SQL statement, try trimming all leading and trailing whitespaces in it. That should probably work. As last name and first names are in two different columns. When you hit space. value something like this John<whitespace> is being sent to the query. Now obviously in your first name column name must be John only, without the whitespace. As query tries to find the name John with trailing white space, it might be failing. Thus your search results are disappearing after you hit space.