Delete row from table - java

I want to delete the current row displayed in jframe from the table contact
I wrote the code
try
{
conn = java.sql.DriverManager.getConnection(connectionURL, "usrnme", "pswd");
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);//also tried with ResultSet.TYPE_SCROLL_SENSITIVE
rs.deleteRow();
rs.next();//it may or may not include in code
}
catch(Exception e){System.out.println( "JDBC error: " + e );}
sql query
String sql="SELECT * FROM contact order by first_name, last_name";
rs=stmnt.executeQuery(sql);
but it throws an exception while running
JDBC error: java.sql.SQLException: 'deleteRow' not allowed because the ResultSet is not an updatable ResultSet.
Help me!

I suggest to do it totally in SQL, where you need to additionally select the (internal) rowid of every row
SELECT c.*, c.rowid FROM contact c ORDER BY first_name, last_name
and afterward delete a row by it row id
DELETE FROM contact c WHERE c.rowid = (?)
this works for Oracle, but every Databasetype does use internal rowid's. For MYSQl you get the rowid by using #rowid as far as I remember

Instead of ResultSet.TYPE_SCROLL_INSENSITIVE, try ResultSet.TYPE_SCROLL_SENSITIVE. That might do the trick. If that doesn't work, try an SQL DELETE statement (w3schools.com) instead to delete the row.
Edit: Now that I reread your code: you need to move to the next row before you call deleteRow. Opening a statement sets the cursor before the first row. If your call to next returns true, your cursor points to the first row. Only if the cursor points to a valid row can you delete the row. HTH.

To make use of updatable ResultSet , your table must contain primary key column. It is the link between data present in ResultSet and DB. Since I infer from your comments your table does not contain primary key, you can delete row using sql query.
String sql = "DELETE FROM contact WHERE first_name='test'";
stmt.executeUpdate(sql);

Related

Checking if table exist in database

I have a JDBC code which retrieves data from database and get queries at runtime. At runtime, it will go to database and will try to get data and write it to a file. If table is not present it gives exception that table not found. How to handle this?
Here I can not use,
ResultSet rs = md.getTable()
I have to check at runtime only.
SQL Example : select * from table; Preparedstatement and ResultSet here,
At runtime this table variable will get names of table when loop above this will iterate. If table is not there then it gives this exception on console.
How to handle this smoothly?
If you dont want that exception, first you should check what tables are there in the database. If the table doesn't exist you can create and avoid that exception.
DatabaseMetaData dbm = con.getMetaData();
ResultSet tables = dbm.getTables(null, null, "your_table_name", null);
if (tables.next()) {
// Table exists
}
else {
// Table does not exist
}
if the table doesnot exist, you may need to create a new table to avoid such exception later.
with hsqlDB you can do a CREATE TABLE IF NOT EXISTS newTable (column details...) if you only wanted to be sure before creating a new one.

Get current sequence Id to store in other tables

We have multiple tables and all are related with first table's primary key (example: id). Id is configured as a sequence and while inserting data into to first table we are using sequence.nextval in the insert query.
Now while inserting data to other tables, how to get current sequence value or current Id.
We have tried below options:
sequence.currval, directly in the insert statement
2.select sequence.currval from dual
Above two options throwing error while using getJdbcTemplate().update().
Could anyone please suggest how to get current sequence value to pass to other tables after inserting data into first table??
If you want to insert the same id (which comes from a sequence) to different tables, simple get it form the first insert and use it in the other inserts.
PrepearedStatement stmt1 = conn.prepareStatement("INSERT INTO TABLE1 (id) VALUES(yoursequence.nextval)", Statemet.RETURN_GENERATED_KEYS);
stmt1.executeUpdate();
ResultSet rs = stmt1.getGeneratedKeys();
rs.next();
long id = rs.getLong(1);
PrepearedStatement stmt2 = conn.prepareStatement("INSERT INTO TABLE2 (id) VALUES(?)");
stmt2.setLong(1,id);
stmt2.executeUpdate();

Retrieving data from a relational database

I have set up 2 two tables - table userid and table data in phpmyadmin. The userid table consists of a single column - id and the table data consists of the following columns- id|name|price. I have added an index in the column id of table userid to point to id of the table data. Now i have a user who makes certain selections inside an android application. I want to insert this data into the table data. I know i have to use jdbc and know how to enter data for table without any index. But i am confused as to how to go about doing it in the case of related tables. The userid is obtained from this link http://android-developers.blogspot.in/2011/03/identifying-app-installations.html. Would someone please tell me how to enter the data using java. (The confusion is how to enter the userid and the corresponding data ).
As long as you're aware of the user id when you're inserting a new record into the data table that's all you need. Basically you'll have:
Statement stmt = conn.createStatement();
stmt.executeUpdate( "INSERT INTO data (id, name, price) VALUES ('id from userid table', 'a name', 'a price')");
Obviously the params aren't escaped properly (they really should be) and there's no testing for errors, but that would get you started.
Then to, for example, select all the data related to a given userid, you would do something like:
Statement stmt = conn.createStatement();
stmt.executeQuery( "SELECT * FROM userid LEFT JOIN data WHERE userid.id = data.id" );

remove duplicate values while insertion

Hi I am trying to insert values from excel sheet into SQL Database in java. SQL database has already some rows inserted by some other techniques. Now I need to insert new rows from excel sheet and should eliminate the duplicate values which are existed in the database as well as in the excel sheet. For that I write a query like this.
First I inserted the records from excelsheet into SQL database by using insert query
Statement.executeUpdate(("INSERT INTO dbo.Company(CName,DateTimeCreated) values
('"+Cname”' ,'"+ts+"');
Later I deleted the duplicate values using delete query.
String comprows="delete from dbo.Company where Id not in"
+ "(select min(Id) from dbo.Company "
+ "group by CName having count(*)>=1)";
statement3.executeUpdate(comprows);
where Id is autoincremented integer.
but it is not good to do insert and then delete.
How do I know the values are already exist? If it is exist how do I remove during insertion???
You can simply fire a SELECT for the CName first. If a record is found, update else insert a new record.
Edited to add code snippet:
ResultSet rs = Statement.query("SELECT Id from dbo.Company where CNAME = '" +Cname + "'");
if(rs.next()) {
// retrieve ID from rs
// fire an update for this ID
} else {
// insert a new record.
}
Alternatively, if you think that there are already duplicates on your table and you want to remove them as well..
ResultSet rs = Statement.query("SELECT Id from dbo.Company where CNAME = '"+Cname + "'");
List idList = new ArrayList();
while(rs.next()) {
// collect IDs from rs in a collection say idList
}
if(!isList.isempty()) {
//convert the list to a comma seperated string say idsStr
Statement.executeUpdate("DELETE FROM dbo.Company where id in ("+ idsStr + ")");
}
// insert a new record.
Statement.executeUpdate(("INSERT INTO dbo.Company(CName,DateTimeCreated) values('"+Cname”' ,'"+ts+"');
Of course good practice is to use PreparedStatement as it would improve performance.
PS: Excuse me for any syntax errors.
One option would be to create a temp table and dump your Excel data there. Then you can write an insert that joins the temp table with the dbo.Company table and only insert the records that aren't already there.
You could do a lookup on each record you want to insert but if you are dealing with large volumes that's not a super efficient way to do it since you will have to do a select and an insert for each record in you excel spreadsheet.
Merge statements are pretty effective in these types of situations as well. I don't think all databases support them (I know Oracle does for sure). A merge statement is basically a combo insert and update so you can do the look up to the final table and insert if not found and update if found. The nice thing about this is you get the efficiency of doing all of this as a set rather than one record at a time.
If you can control the DB schema, you might consider putting a unique contraint for whatever column(s) to avoid duplicating. When you do your inserts, it'll throw when it tries to add the dup data. Catch it before it tosses you all the way out.
It's usually good to enforce constraints like this on the DB itself; that means no one querying the database has to worry about invalid duplicates. Also, optimistically trying the insert first (without doing a separate select first) might be faster.

Prepared statement with wildcard not returning certain rows but query returns all rows?

I'm using JTDS as a driver to connect to SQL server.
Here's the query that's giving me problems:
SELECT EmpID,FirstName,LastName,CompanyName,DepartmentName,JobTitle,HireDate FROM Employees where UPPER(FirstName) LIKE 'KEVIN%'
It returns 2 rows on SQL Server. One that has 'KEVIN' in upper case and another that has 'Kevin' like so. I used the wildcard to make sure I get both results. In my EmployeeDAO class I'm using the following:
ps = con.prepareStatement("SELECT EmpID,FirstName,LastName,CompanyName,"
+ "DepartmentName,JobTitle,HireDate FROM Employees WHERE UPPER(FirstName) LIKE ?");
ps.setString(1, FirstName + "%");
rs = ps.executeQuery();
And then of course I put KEVIN on my main. It only returns ONE row, which is the 'Kevin' row.
How do I fix this so it returns all rows?
Your query looks fine (although I would uppercase the parameter value before setting it, to make it more robust). The problem is just in the way how you're collecting the rows from the ResultSet. Likely you're plain overriding the previous row with the next row so that you end up with only one row (the last one) in your collection.
Default collation of the SQL Server installation is SQL_Latin1_General_CP1_CI_AS and it is not case sensitive.
Change collation of the query:
SELECT Col1
FROM Table1
WHERE Col1 COLLATE Latin1_General_CS_AS LIKE 'KEVIN%'

Categories