Deleting the last row in a table. SQL/Netbeans - sql

In java, i am trying to delete the last row of my database. The database has 15 rows and i want to the delete the 15th one. The columns are called Initials and Score.
Intials Scores
rows# 1. ADS 2343
2. DDE 5454
15. TBK 332
I can't have it selecting TBK because i'm wanting it to delete the 15th one no matter what it is so a new one can be added. Everywhere I've looked it's always has to be specific or a delete all rows. Can anyone help? Many thanks to those who help. :)

Assuming id is an identity column
DELETE FROM table
WHERE id = (SELECT MAX(id) FROM table)

OP : I am trying to delete the last row of my database.
make resultset updatable : ResultSet.CONCUR_UPDATABLE);
set cursor to last record : resultSet.last();
delete last Record : resultSet.deleteRow();
for further use of rs you should set : resultSet.beforeFirst();
private static int delLastRow(ResultSet resultSet) {
if (resultSet == null) {
return 0;
}
try {
resultSet.last();
int delID = resultSet.getInt(1);
resultSet.deleteRow();
System.out.println("Deleted id :" + delID);
resultSet.beforeFirst();
return delID;
} catch (SQLException exp) {
exp.printStackTrace();
} finally {
try {
resultSet.beforeFirst();
} catch (SQLException exp) {
exp.printStackTrace();
}
}
return 0;
}
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
try{
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(DB_URL,USER,PASS);
stmt = conn.createStatement(
ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
//rs will be scrollable, will not show changes made by others,
//and will be updatable
String sql;
sql = "SELECT * FROM `order details`";
ResultSet rs = stmt.executeQuery(sql);
System.out.println("Deleted id :"+ delLastRow(rs));
....
}

Related

Creating Trigger to auto-increment id by sequence in JDBC

I am writing methods through JDBC to create a table and a sequence to recall in a Trigger, I want to set up an id column which auto-increments before every insert on the table. I succeeded in building both the createTable method and the createSequence method in the DAO, but when I run the method to create the Trigger I got the java.sql.SQLException: Missing IN or OUT parameter at index:: 1
public void createTrigger() {
PreparedStatement ps;
StringBuilder queryTrigger = new StringBuilder();
queryTrigger.append("CREATE OR REPLACE TRIGGER ");
queryTrigger.append(Tables.getInstance().getName() + "_INSERTED\n");
queryTrigger.append("BEFORE INSERT ON " + Tabelle.getInstance().getName());
queryTrigger.append("\nFOR EACH ROW\n");
queryTrigger.append("BEGIN\n");
queryTrigger.append("SELECT " + Tables.getInstance().getName() + "SEQ.NEXTVAL\n");
queryTrigger.append("INTO :new.id\n");
queryTrigger.append("FROM dual;\n ");
queryTrigger.append("END;\n");
queryTrigger.append("/\n");
queryTrigger.append("ALTER TRIGGER " +Tabelle.getInstance().getName() + "_INSERTED ENABLE\n");
queryTrigger.append("/\n");
String stringQueryTrigger = queryTrigger.toString();
Connection conn = JDBCUtility.openConnection();
try {
ps = (PreparedStatement) conn.prepareStatement(stringQueryTrigger);
ps.executeUpdate();
ps.close();
} catch(SQLException e) {
e.printStackTrace();
}
JDBCUtility.closeConnection(conn);}
Here instead the creation of the table does actually work even if I don't
write the classic lines with parametrized "?" for the preparedStatement.setString(index, String)
public void createTable(Columns c) {
PreparedStatement ps;
StringBuilder query = new StringBuilder();
query.append("CREATE TABLE " + Tabelle.getInstance().getName() + "(");
query.append(Columns.getInstance().getColumnName() + " ");
query.append(Columns.getInstance().getDataType());
if(Columns.getInstance().isNullOrNot() == true) {
query.append(" NOT NULL");
}
else {
query.append("");
}
if(Columns.getInstance().isPrimaryKeyOrNot() == true) {
query.append(" PRIMARY KEY)");
}
else {
query.append(")");
}
String queryToString = query.toString();
Connection conn = JDBCUtility.openConnection();
try {
ps = (PreparedStatement) conn.prepareStatement(queryToString);
ps.executeUpdate();
ps.close();
} catch(SQLException e) {
e.printStackTrace();
}
JDBCUtility.closeConnection(conn);
}
//EDIT
turns out that is enough to substitute the PreparedStatement with a simple Statement, to get rid of the indexes mechanism and get the DB to accept the query
I would suggest creating an auto-increment sequnce in oracle that can be used for all ids and just add the string id.NextVal to the string query
What I mean is:
Rem in oracle create sequence
CREATE SEQUENCE ID
START BY 1
INCREMENT 1
// in java to execute query
String query = "INSERT INTO TABLE VALUES(ID.NEXTVAL);" ;
//rest of code

Oracle columns update not happpening

I am trying to update a few columns in a Oracle table from my C# code.
Here is my method:
private static bool UpdateOracleTable(OracleTable table, string whereClause, List<int> entIDs)
{
try
{
var tableName = table.ToString();
using (OracleConnection conn = new OracleConnection(_oracleConnection))
{
conn.Open();
foreach (var id in entIDs)
{
whereClause = String.Format(whereClause, id);
var query = Resources.UpdateOracle;
query = String.Format(query, tableName, "20", DateTime.Now.ToString("yyyy/MM/dd"), whereClause);
using (OracleCommand cmd = new OracleCommand(query, conn))
{
cmd.ExecuteNonQuery();
}
}
}
return true;
}
catch (Exception ex)
{
Log.Debug(LogType.Error, ex);
return false;
}
}
Here is the Query:
UPDATE
{0}
SET
SYNC_STATUS = '{1}'
,SYNC_DATE = TO_DATE('{2}', 'yyyy/mm/dd')
{3}
And the where clause will look something like:
WHERE ID = {0}
This method updates about 10 records, and the rest stays null. This mehod does return true, and I have debugged, no exception is thrown.
Why does it not update all records?
This isn't an answer but might help debug the problem.
Instead of the like:
cmd.ExecuteNonQuery();
put in this:
int count = cmd.ExecuteNonQuery();
if (count == 0)
{
Console.WriteLine("");
}
Put a break on the Console.WriteLine("") and run it. The debugger will stop if no rows were updated. You can then check the query, and whether or not that ID actually exists.
The problem was with the WHERE clause. Since it contains a place holder {0}, after I I formatted the WHERE clause, the ID always stayed to the value it was formatted with first.
This is what my new method looks like.
private static bool UpdateOracleTable(OracleTable table, string whereClause, List<int> entIDs)
{
try
{
var tableName = table.ToString();
using (OracleConnection conn = new OracleConnection(_oracleConnection))
{
conn.Open();
foreach (var id in entIDs)
{
string originalWhere = whereClause;
originalWhere = String.Format(originalWhere, id);
var query = Resources.UpdateOracle;
query = String.Format(query, tableName, "20", DateTime.Now.ToString("yyyy/MM/dd"), originalWhere);
using (OracleCommand cmd = new OracleCommand(query, conn))
{
bool success = cmd.ExecuteNonQuery() > 0;
}
}
}
return true;
}
catch (Exception ex)
{
Log.Debug(LogType.Error, ex);
return false;
}
}
As can be seen, I added a variable 'originalWhere', that gets formatted, but most importantly, is being set to original WHERE clause parameter passed, so that it will always contain the place holder.

How to query database and return single row only

I'm new to programming and I'm trying to do simple projects to learn more. I've done researching, but I can't seem to find a solution to my problem. Perhaps, my program is not properly structured, but here it goes:
THIS BLOCK WILL VALIDATE IF THE ENTERED EMPLOYEE ID ALREADY EXISTS IN DATABASE. THIS IS CALLED IN A SERVLET
public boolean login(String employeeID) throws SQLException {
String sql = "select count(*) as count from employees where emp_id=?";
statement = connection.prepareStatement(sql);
statement.setString(1, employeeID);
rs = statement.executeQuery();
if (rs.next()) {
count = rs.getInt("count");
}
rs.close();
if (count == 0) {
return false;
} else {
return true;
}
}
/* METHOD BELOW ITERATES THE FIELDS FROM MYSQL DATABASE, BUT IT DISPLAYS ALL OF IT.
I JUST WANT TO GET A SINGLE ROW MATCHING THE EMPLOYEE ID PARAMETER ENTERED.*/
public List<EmployeeNumber> _list() throws SQLException {
List<EmployeeNumber> result = new ArrayList<>();
String sql = "select * from employees";
statement = connection.prepareStatement(sql);
rs = statement.executeQuery();
if (rs.next()) {
EmployeeNumber emp = new EmployeeNumber();
emp.setEmployeeNumber(rs.getString(1));
emp.setFirstName(rs.getString(2));
emp.setLastName(rs.getString(3));
emp.setEmail(rs.getString(4));
emp.setDepartment(rs.getString(5));
emp.setFirstApprover(rs.getString(6));
emp.setSecondApprover(rs.getString(7));
result.add(emp);
}
if (rs != null) {
rs.close();
}
if (statement != null) {
statement.close();
}
if (connection != null) {
connection.close();
}
return result;
}
}
I think it has something to do with my SQL Query statement but I can't figure out how to fix it.
So in a nutshell, when I submit the employee ID from JSP page, it will validate if that exists, and if it does, I want to display all the column fields within the same row where this employee ID is positioned. How do I do that? Results will be displayed on another JSP page.
Thank you.
You're first counting how many employees have the given ID. Then you're selecting all the rows from the employee table.
Skip the first query, and only use the second one, but by adding a where clause, just as you did with the first query:
select * from employees where emp_id=?
Then after you've bound the parameter (as you did for the first query), test if there is a row returned:
if (rs.next()) {
// get the data, and return an EmployeeNumber instance containing the data
}
else {
// no employee with the given ID exists: return null
}
Note that the method shouldn't return a List<EmployeeNumber>, but an EmployeeNumber, since you only want to get 1 employee from the table.
Maybe try something like this?
String sql = "select count(*) as count from employees where emp_id=?";
statement = connection.prepareStatement(sql);
statement.setString(1, employeeID);
int count = statement.ExecuteScalar();
if (count == 0) {
return false;
} else {
return true;
}
}
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executescalar(v=vs.110).aspx
You can also set a breakpoint and step through your code and see where the exception is being thrown. That would help us, knowing the exception message and where it's breaking.

Existing posts keep on re-add upon deletion of selected row in jTable

I try to refresh the data of jTable upon deletion of selected row. Here are my codes to set up table :
private JTable getJTableManageReplies() {
jTableManageReplies.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
jTableManageReplies.getSelectionModel().addListSelectionListener(
new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
int viewRow = jTableManageReplies.getSelectedRow();
// Get the first column data of the selectedrow
int replyID = Integer.parseInt(jTableManageReplies.getValueAt(
viewRow, 0).toString());
eForumRepliesAdmin reply = new eForumRepliesAdmin(replyID);
replyID = JOptionPane.showConfirmDialog(null, "Are you sure that you want to delete the selected reply? " , "Delete replies", JOptionPane.YES_NO_OPTION);
if(replyID == JOptionPane.YES_OPTION){
reply.deleteReply();
JOptionPane.showMessageDialog(null, "Reply has been deleted successfully.");
SetUpJTableManageReplies();
}
}
}
});
return jTableManageReplies;
}
public void SetUpJTableManageReplies() {
DefaultTableModel tableModel = (DefaultTableModel) jTableManageReplies
.getModel();
String[] data = new String[5];
db.setUp("IT Innovation Project");
String sql = "Select forumReplies.reply_ID,forumReplies.reply_topic,forumTopics.topic_title,forumReplies.reply_content,forumReplies.reply_by from forumReplies,forumTopics WHERE forumReplies.reply_topic = forumTopics.topic_id ";
ResultSet resultSet = null;
resultSet = db.readRequest(sql);
jTableManageReplies.repaint();
tableModel.getDataVector().removeAllElements();
try {
while (resultSet.next()) {
data[0] = resultSet.getString("reply_ID");
data[1] = resultSet.getString("reply_topic");
data[2] = resultSet.getString("topic_title");
data[3] = resultSet.getString("reply_content");
data[4] = resultSet.getString("reply_by");
tableModel.addRow(data);
}
resultSet.close();
} catch (Exception e) {
System.out.println(e);
}
}
And this is my sql statement :
public boolean deleteReply() {
boolean success = false;
DBController db = new DBController();
db.setUp("IT Innovation Project");
String sql = "DELETE FROM forumReplies where reply_ID = " + replyID
+ "";
if (db.updateRequest(sql) == 1)
success = true;
db.terminate();
return success;
}
I called the repaint() to update the table data with the newest data in database and it works. I mean the data after deletion of certain row. However, the existing posts will keep on re-add. Then I add the removeAllElement method to remove all the existing posts because my sql statement is select * from table. Then, there is an error message which is ArrayIndexOutOfBoundsException. Any guides to fix this? Thanks in advance.
I called the repaint() to update the table data with the newest data
in database and it works.
There is no need to call repaint method when data is changed. Data change is handled by the Table Model (DefaultTableModel in this case.) And fireXXXMethods are required to be called whenever data is changed but you are using DefaultTableModel even those are not required. (Since by default it call these methods when ever there is a change.)
I think the problem is in the valuesChanged(..) method. You are getting the value at row 0 but not checking whether table has rows or not. So keep a constraint.
int viewRow = jTableManageReplies.getSelectedRow();
// Get the first column data of the selectedrow
if(jTableManageReplies.getRowCount() > 0)
int replyID = Integer.parseInt(jTableManageReplies.getValueAt(viewRow, 0).toString());

when is an EJB CMP entity bean actually created

I have a session bean that provides a business method, in which it creates several CMP entity beans, something like this
public void businessMethod(int number) {
try {
MyBeanHome home = lookupMyBean();
DataSource dataSource = getMyDataSource();
Statement statement = dataSource.getConnection().createStatement();
ResultSet result;
String tableName = "MYBEAN";
for (int i = 0; i < number; i++) {
result = statement.executeQuery("select max(ID) + 1 from " + tableName);
result.next();
int newID = result.getInt(1);
System.out.println(newID);
MyBeanLocal lineLocal = home.create(newID);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
The create method of MyBean simply creates a new bean with newID. However, the above code only works with number = 1. If number > 1, it tries to create a second bean with the same ID (System.out.println(newID); prints the same value). I'm guessing the new bean is not stored in the database yet, and thus the query returns the same value. What can be done to this?
Many thanks!
I figured it out that the transaction is only executed when the business method finishes, so the first entity beans would not be stored in the database for retrieval. A simple solution is below
public void businessMethod(int number) {
try {
MyBeanHome home = lookupMyBean();
DataSource dataSource = getMyDataSource();
Statement statement = dataSource.getConnection().createStatement();
ResultSet result;
String tableName = "MYBEAN";
result = statement.executeQuery("select max(ID) + 1 from " + tableName);
result.next();
int newID = result.getInt(1);
for (int i = 0; i < number; i++) {
System.out.println(newID);
MyBeanLocal lineLocal = home.create(newID++);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}