Delete row using Java PreparedStatement not always working - java

When i'm trying to delete a last row in a table using a PreparedStatement (I'm using a MySQL database), the row wasn't been deleted, I tried to use a DELETE FROM... command and a TRUNCATE command (using the executeUpdate() command), but none of those commands deleted that last row, What should I do, in order to be able to delete that last row?
this is the command i have written:
String sqlDelete = "DELETE FROM free_time WHERE therapist_id=? AND from=? AND to=? AND date=?";
And I have checked that the parameters that i'm sending to the Prepared Statement are correct, but still, the row isn't been deleted.
Thanks in advanced.

Last row doesn't mean anything in a relational database. You don't need to know how the rows are stored.
You should be using a WHERE clause to identify what you need to DELETE.
I wouldn't recommend TRUNCATE.

You are using key words, and obviously suppressing exceptions ;).
String sqlDelete = "DELETE FROM free_time WHERE therapist_id=? AND `from`=? AND `to`=? AND `date`=?";

Related

Delete row with confirmation from Oracle table

I have this SQL query which is used to delete users.
DELETE FROM USERS WHERE USERNAME = ?
The problem is that I don't know is there any row success row removal or not. I always get success at the end.
Is there any way to get for example some confirmation from Oracle that row is deleted in my Java code?
executeUpdate() method of PreparedStatement gives You the number of rows deleted.If no rows have been deleted by the query You get 0.I think that's the easiest solution.
If You need to know which rows have been deleted You can user "Returning" clause, that will give You rows deleted.
Regards
You can use SQL%ROWCOUNT. It is an implicit cursor that gives the number of rows affected by SQL statement
declare
begin
DELETE FROM USERS WHERE USERNAME = ?;
dbms_output.put_line('Total Deleted:' ||sql%rowcount);
end;
This will give you the count of the number of rows deleted.

Transfer mysql binary log into select in CDC

I would like to do a real time reading from mysql.
The idea is simple. I use the binary log to trigger the select statement.
Meanwhile I'd like to read only the new rows on every change.
And currently I just consider insert.
So when someone do
insert into sometable(uid,somecolumn) values(uid,something)
My code will be triggered and do
select from sometable where uid=uid
Of course I have already written down which columns are the primary key because it seems no information from binlog.
I cannot find a tool to analysis mysql insert statement. So I use the regex to find out which column equals which value, then extract primary keys.
BUT the real problems what will happen if I do
Insert into `table` (`col`) values (select 0 as `col` from `dummy`);
How can I find out the col=0?
Is it impossible that make a select statement that select the new changed rows, triggered by the insert statement?
In a TRIGGER, you have access to the OLD and NEW values. With them, you can write code (in the TRIGGER) to log, for example, just the changes. Something like...
IF NEW.col1 != OLD.col1 THEN INSERT INTO LOG ...; END;
IF NEW.col2 != OLD.col2 THEN INSERT INTO LOG ...; END;

Table rows seem to be disapearing

I have a ton of raw html files that I'm parsing and inserting to a MySQL database via a connection in Java.
I'm using "REPLACE INTO" statements and this method:
public void migrate(SomeThread thread) throws Exception{
PreparedStatement threadStatement = SQL.prepareStatement(threadQuery);
thread.prepareThreadStatement(threadStatement);
threadStatement.executeUpdate();
threadStatement.close();
for(SomeThread.Post P : thread.threadPosts){
PreparedStatement postStatement = SQL.prepareStatement(postQuery);
P.preparePostStatement(postStatement);
postStatement.executeUpdate();
postStatement.close();
}
}
I am running 3 separate instances of my program each in its own command prompt, with their own separate directory of htmls to parse and commit.
I'm using HeidiSQL to monitor the database and a funny thing is happening where I'll see that I have 500,000 rows in a table at one point for example, then I'll close HeidiSQL and check back later to find that I now have 440,000 rows. The same thing occurs for the two tables that I'm using.
Both of my tables use a primary key called "id", each of their ID's have their own domain but it's possible their values overlap and are overwriting each other? I'm not sure if this could be an issue because I'd think SQL would differentiate between the table's "local" id values.
Otherwise I was thinking it could be that since I'm running 3 separate instances that each have their connection to the DB, some kind of magic is happening where right as one row is being committed, the execution swaps to another commit statement, displaces the table, then back to the first commit and then some more magic that causes the database to roll back the number of rows collected.
I'm pretty new to SQL so I'm not too sure where to start, if somebody has an idea about what the heck is going on and could point me in the right direction I'd really appreciate it.
Thanks
You might want to use INSERT INTO instead of REPLACE INTO.
Data doesn't disappear.
Here are some tips:
Do you have another thread running that actually deletes entries?
Do other people have access to the database?
Not sure what HeidiSQL may do. To exclude that possibility maybe use MySQL Workbench instead.
Yeah now that I run a COUNT(*) query against my tables I see that all my rows are in fact there.
Most likely the heidiSQL summary page is just a very rough estimate.
Thanks for the suggestion to use workbench pete, I will try it and see if it is better than Heidi as Heidi is freezing up on me on a regular basis.

Search for text mysql database is really slow

I have a table on mySql with around 300,000 records. One column is a VARCHAR and it contains a link (let's say, http://www.mysite.com/123012993)
Using Java, everytime I create a new record I need to know if it already exists. The exact link must be on the database. If it's new, then proceed to insert. Else, do nothing.
So I have the following:
String selectString = "Select count(link) from records_table where link = ?";
PreparedStatement ps = conn.prepareStatement(selectString);
ps.setString(1, "http://www.mysite.com/123012993");
ResultSet rsFinding = ps.executeQuery();
rsFinding.next();
if (t != 0) return false;
else { // do normal insert }
However, the query to search the Text is very slow, we are talking around 1 minute. The insert itself is very fast. Everything runs on localhost.
Is this the right way to search for the text? Or should I index the database?
I was thinking on implementing a hashkey and narrow the results, but a query on 300,000 records shouldn't be to heavy I believe.
Thanks
A couple of things:
PreparedStatement should not be prepared each time again and again. Prepare and reuse.
Your t is defined nowhere.
Let the DB do the work: I guess each DB has a possibility to handle duplicates. For MySql there's INSERT ... ON DUPLICATE KEY UPDATE ...
So use this command
INSERT ? INTO records_table ON DUPLICATE KEY UPDATE link = link
The part link = link is a no-op to make the syntax looking good for the MySql parser.
There's also INSERT IGNORE which is bit easier to use (no need for the no-op), but it ignores more problems, which is bad.
I forgot to mention that you need a unique key constraint on link (a primary key is a special case of UK as thus fine too).

Making changes to my program after updating my database?

Sorry if my question is not specific or if it has been answered before. I tried looking for it and for a better way to ask but this is the most accurate way.
I have developed a program in Java in which I insert a new row into my database in the following way:
INSERT INTO table_name VALUES (?,?,?)
The thing is that I have this query in many parts of the program, and now I decided to add a fourth column to my table. Do I have to update EVERY SINGLE query with a new question mark in the program? If I dont, it crashes.
What is the best way to proceed in these cases?
YES.
you need to add extra ? (parameter placeholder) because you are using implicit INSERT statement. That means that you didn't specify the column names of the table to which the values will be inserted.
INSERT INTO table_name VALUES (?,?,?)
// the server assumes that you are inserting values for all
// columns in your table
// if you fail to add value on one column. an exception will be thrown
The next time you create an INSERT statement, make sure that you specify the column names on it so when you alter the table by adding extra column, you won't update all your place holders.
INSERT INTO table_name (Col1, col2, col3) VALUES (?,?,?)
// the server knows that you are inserting values for a specific column
Do I have to update EVERY SINGLE query with a new question mark in the program?
Probably. What you should do, while you're updating every single one of those queries, is to encapsulate them into an object, probably using a Data Source pattern such as a Table Data Gateway or a Row Data Gateway. That way you Don't Repeat Yourself and the next time you update the table, you only have one place to update the query.
Because of the syntax you've used, you might run some issues. I've referring to the lack of column names. Your INSERT queries will start failing as soon as you change your table structure.
If you had used the following syntax:
INSERT INTO table_name (C1, C2, C3) VALUES (?,?,?)
assuming your new column has a proper default value, then it would've work fine.

Categories