I have a dropdown list that holds all the columns name from the table. When the user selects a certain column name and enters a specific value to search for along with two different dates, I get that information and update the table as shown below.
But before updating I want to prompt a dialog box asking the user "This many rows will be updated, do you want to do this?". Can I modify something in this code to get that count before it's updated or is there a better way to do this?
sql.append(" UPDATE Table_jack ");
sql.append(" set date = to_date('" + this.getNewDate() + "','MM/DD/YYYY')");
if ((this.getSelectedDDL() != null)&& (this.getSelectedDDL().equals("1"))){
sql.append(" where id_nbr =" + this.getValue() + "'");
sql.append(" and date between to_date('" + this.getDateFrom() + "','MM/DD/YYYY') and to_date('" + this.getDateTo() + "','MM/DD/YYYY')");
}
if ((this.getSelectedDDL() != null)&& (this.getSelectedDDL().equals("2"))){
sql.append(" where name =" + this.getValue() + "'");
sql.append(" and date between to_date('" + this.getDateFrom() + "','MM/DD/YYYY') and to_date('" + this.getDateTo() + "','MM/DD/YYYY')");
}
ResultSet rset = db.executeQuery(sql.toString(),true);
Rather than trying to get a count before you issue the update, get a count of the number of rows actually updated and display that to the user before issuing the COMMIT (or ROLLBACK).
The Statement.executeUpdate method returns the number of rows that the UPDATE statement modified. If you used that rather than executeQuery, you could get a row count from the UPDATE statement. You could then present that to the user before ending the transaction.
You would have to build and run a separate select count(*) query to get the number of rows to be updated. There is also the chance that the data could change between the time you do your select count(*) and update the table. If that is an issue, you would need to lock the table for the duration of your queries.
Related
I'm trying to do a very simple thing: know if a row exists in my SQLite DB.
The Statement.execute(sqlquery) function should allow me to do this, as it reads in the description of the function: if the SQL query returns 1 or more rows the return = true, if the SQL query returns 0 rows its return = false.
I don't think is necessary I go deeper into the structure of my DB or my program. I'm doing this quite simple return
System.out.println("1---" + stat1.execute("SELECT EXISTS(SELECT 1 FROM " + TABLA_OFERTAS + " WHERE " + OFERTAS_COL_ID + " = '" + id + "' AND " + OFERTAS_COL_ASIGNADA + " = 'SI')"));
Where id is a variable that iterates through every row of the table. I'm just filtering for every row if it has a column with a YES (that should return a true), if that particular column has another thing the SQL query shouldn't match and it should return no value so it should return a false.
If I use this same select sentence on an external SQL program this actually returns 0 values, but for some reason, while in my own program this System.out ALWAYS returns true.
I've checked the "id" variable and it works fine. I don't know what to do.
Thanks in advance for any help you can provide. Maybe I've misunderstood the method Javadoc. I don't know.
If more info is needed I'm willing to share it.
Your query uses EXISTS which returns 1 if the conditions are satisfied or 0 if not.
So, you get always 1 row.
Moreover, the method execute() always returns true, when the sql statement is a SELECT query.
What you need is to check the result of the query if it returned 1 or 0, but you can do it without EXISTS, with a PreparedStatement and ? placeholders in the sql statement, which is the safe way to pass parameters to a query:
String sql = "SELECT 1 FROM " + TABLA_OFERTAS + " WHERE " + OFERTAS_COL_ID + " = ? AND " + OFERTAS_COL_ASIGNADA + " = 'SI'";
PreparedStatement st = conn.prepareStatement(sql)); // conn is your connection object
st.setInt(1, id);
ResultSet rs = st.executeQuery();
System.out.println("1---" + rs.next());
rs.next() will return true if the query returned at least 1 row, or false if there are no rows.
I assume that id is an integer, but if it is a string change to:
st.setString(1, id);
I am trying to figure out a piece of code that has existed as is for several years but has recently started behaving differently (not sure if it is because of newer versions of jre or the environment the code is being run in but I don't know enough to tell). Anyways, basically the gist of the code pasted below is that I process one record at a time and insert it into a new table. The idea is that I only ever insert 1 row at a time. This code is from like 2000 or something and back then the engineers decided to throw in super paranoid sanity checks to make sure that one and only one record got inserted into the said table. All of a sudden this piece has been throwing the exceptions that indicate that the number of rows inserted was NOT 1 (Unfortunately, I don't know how many rows got inserted since the code lacks that piece of logging).
//
// If the result set is empty, then get the next master record id and insert a new record into the
// Holding_Tank_Master_Records.
//
if ( !mrRecords.next() )
{
// a new master record is needed
mrid = this.getMasterRecordId();
log.debug("new master record id = " + mrid);
insertSQL = new String("INSERT INTO Holding_Tank_Master_Records (" +
"Master_Record_Id, Probe_Date, Import_Filename, " +
"Pennies, Nickels, Dimes, Quarters, " +
"Half_Dollars, SBA_Dollars, One_Dollar_Bills, " +
"Five_Dollar_Bills, Ten_Dollar_Bills, Twenty_Dollar_Bills) " +
"VALUES( " + mrid + ", '" + curProbeDate.toString() + "', 'Avail AVL APC', " +
"0, 0, 0, 0, 0, 0, 0, 0, 0, 0 )");
int result = mrStatement.executeUpdate(insertSQL);
if ( result == 1 )
{
log.debug ( "NEW MASTER RECORD created for " + curProbeDate.toString() );
}
else
{
log.debug("Failed! SQL: " + insertSQL);
String strErrMsg = "Failed to insert new record into Holding_Tank_Master_Records. " +
"Master_Record_Id = " + mrid + " Probe_Date = " + curProbeDate.toString() +
"Vehicle Farebox Id = " + Integer.toString(vehicleID) + ".";
log.error( strErrMsg );
throw new AvailFaretoolException( strErrMsg );
}
}
So, what I am seeing is the 'Failed!' SQL message along with the custom exception being thrown lending me to believe that the number of rows inserted was NOT 1.
Has anyone seen anything like this before? Can you spot an issue here? By the way, if I were to run the SQL via SQL management studio, it works just fine with a message telling me 1 row was inserted. I know that the SQL running through the code isn't causing any SQL exceptions (which in any case would have caused the code flow to fall straight to my catch block, correct?)
Thanks for looking at this!
K
Edit:
Just wanted to add information regarding research I have done so far on this topic:
The API documentation for the executeUpdate mentions that the 'update count' it returns is either (1) the row count for SQL Data Manipulation Language (DML) statements or (2) 0 for SQL statements that return nothing
Since the statement is a pure insert statement, I don't understand how it could return anything but a non-negative integer. I mean, the only possible outcome of an insert statement is a row count, right?
I have a doubt about adding days to Date in MySQL database.
The following is my code:
res=stat.executeQuery("select st_date from tmp1 where st_date = '"+t1.getText()+"'");
while(res.next())
{
System.out.println(res.getDate(1));
int i=0;
while(i<14)
{
statement.executeUpdate("Insert into datetab values(DATE_ADD('"
+res.getDate("st_date")+"',INTERVAL 1 DAY),'"+tempname+"')");
i=i+1;
}
}
All the updates in datetab table occur, but there is a problem. I will explain the problem with an example. If the date from tmp1 table is 28-12-2000, then after executing the insert query with date_add(), what happens is that 13 new inserts are happening, but all those inserts are "29-12-2000".
If the date from tmp1 table is 28-12-2000 Then after executing the insert query with date_add(), what happens is that 13 new inserts are happening, but all those inserts are "29-12-2000".
Because that is exactly what you are asking for. Your insert statement is:
"Insert into datetab values(DATE_ADD('" + res.getDate("st_date") +
"',INTERVAL 1 DAY),'" + tempname + "')"
Since read.getDate is not changing in the loop, the same value is inserted in every interation.
Instead of "Interval 1 DAY", use "Interval " + i + " Day" should insert different days. Is that what you are looking for?
I'm working on a database project about adding, editing and deleting registries to a Students table which has fields:
Last_names, Names, IcNumber, Average, Entry_mode, Career and Change
In the editing frame i have a field where user types the icnumber of the student to edit its data, asks for the new data and saves it to a "Students" data structure, and then reupdates the registry with the new data:
String stmnt = "Insert Into Students (Last_names, Names, IcNumber, Average, " +
"Entry_mode, Career, Change) Values ('" + student.getLastNames() +
"', '" + student.getNames() + "', '" + student.getIcNumber() + "', " +
student.getAverage() + ", '" + student.getEntry() + "', '" +
student.getCareer() + "', '" + student.getChange() + "') " +
"Where IcNumber = '" + field.getText() + "'";
statement.execute(stmnt);
And i get this Error message:
[Microsoft][Microsoft Access ODBC Driver] "Query input must contain at least one table or query."
I have tried a similar SQL Instruction in the adding registry area of my program without the "Where" condition and works good, anyone knows about that error?
You should use a subquery, first the SELECT part with WHERE and then the INSERT part
Something like:
if (cond){
(SELECT.....)
(INSERT INTO...)}
Why are you using where in a insert statement? Where clause is applicable in select, update and delete statements but not in insert. Also I don't see any need of the where clause in your query.
Simply use the insert statement without where clause.
Use an INSERT statement to add a new record. A WHERE clause does not belong in an INSERT statement.
If you're editing an existing record, then you should use an UPDATE statement, and a WHERE clause makes sense to identify which record to change.
This is currently my MySQL UPDATE query, which is called from program written in Java:
String query = "UPDATE maxday SET DatePressureREL = (SELECT " +
"Date FROM ws3600 WHERE PressureREL = (SELECT MAX" +
"(PressureREL) FROM ws3600 WHERE Date >= '" + Date +
"') AND Date >= '" + Date + "' ORDER BY Date DESC LIMIT 1), " +
"PressureREL = (SELECT PressureREL FROM ws3600 WHERE " +
"PressureREL = (SELECT MAX(PressureREL) FROM ws3600 " +
"WHERE Date >= '" + Date + "') AND Date >= '" + Date +
"' ORDER BY Date DESC LIMIT 1), ...";
try {
s.execute(query);
}
catch (SQLException e) {
System.out.println("SQL error");
}
catch(Exception e) {
e.printStackTrace();
}
Let me explain first, what does it do. I have two tables, first is ws3600, which holds columns (Date, PressureREL, TemperatureOUT, Dewpoint, ...). Then I have second table, called maxday, which holds columns like DatePressureREL, PressureREL, DateTemperatureOUT, TemperatureOUT,... Now as you can see from an example, I update each column, the question is, is there a faster way? I am asking this, because I am calling MAX twice, first to find the Date for that value and secondly to find the actual value. Now I know that I could write like that:
SELECT Date, PressureREL FROM ws3600 WHERE PressureREL =
(SELECT MAX(PressureREL) FROM ws3600 WHERE Date >= '" +
Date + "') AND Date >= '" + Date + "'
ORDER BY Date DESC LIMIT 1
That way I get the Date of the max and the max value at the same time and then update with those values the data in maxday table. But the problem of this solution is, that I have to execute many queries, which as I understand takes alot more time compared to executing one long mysql query because of overhead in sending each query to the server.
If there is no better way, which solution beetwen this two should I choose. The first, which only takes one query but is very unoptimized or the second which is beter in terms of optimization, but needs alot more queries which probably means that the preformance gain is lost because of overhead in sending each query to the server?
Doing 2 queries isn't really a problem for me, but they should be in a transaction (the reads and the write), this way you'll be sure that your update values are not wrong. With one query you do not have this problem.
I think the time lost in reading some data is nothing regarding the time lost by performing a write operation. A write operation is not by definition a fast thing, you could have triggers, you're maybe emptying the query cache from all requests impacting this table, the database needs to sync your write on disk, etc.
The more important thing for you is to keep your process simple, readable, and logic.
1) I think the problem goes deeper than just SQL optimization. Do you think this could be modeled differently where you don't have to migrate data like this (this much, and this often too btw) in the first place? Perhaps just using a FK/cross table to link the two together instead of migrating every field?
2) One query is much better than using JDBC to constantly go back and forth over the connection with new statements. That is a very expensive operation (each time). You will always want to stick to condensing queries into one as opposed to using iteration to make execute many statements.
Working from the inside out, it looks like all your subqueries do the same thing.
What's the point of having a where clause that does Date >= '" + Date + "') AND Date >= '" + Date + "' ?
Without going into column names or technical details, what are the purposes of your two tables?
String query = #"UPDATE maxday SET DatePressureREL = (SELECT Date FROM ws3600 WHERE PressureREL = (SELECT MAX(PressureREL) FROM ws3600 WHERE Date >= #Date) AND Date >= #Date ORDER BY Date DESC LIMIT 1), PressureREL = (SELECT PressureREL FROM ws3600 WHERE PressureREL = (SELECT MAX(PressureREL) FROM ws3600 WHERE Date >= #Date) AND Date >= #Date ORDER BY Date DESC LIMIT 1), ...";
After this, ideally if you were using a SelectCommand of some type instead of a string, you would
query.Parameters.Add(new MySqlParameter("#Date", yourdate));
Alternatively, you can just do this, although it opens you up to sql injection
query = query.replace("#Date", "'" + Date "'");
Either way, it makes the query considerably more legible.
If you can get all the values in one select query, this might work. Use a stored procedure accepting one parameter (date) that does:
One select statement, storing the values in a cursor, and
One update statement, using the values in the cursor.
Cursor Example