Count deleted records, returns 0 - sqlite

I perform a DELETE in my table from my servlet by calling a method action.deleteBox(box); which executes the delete function
deleteBox method
Connection c = null;
PreparedStatement stm = null;
sq = "DELETE FROM BOXES WHERE ...";
try {
Class.forName(typeDB);
c = DriverManager.getConnection(path);
stm = c.prepareStatement(sq);
//...
stm.executeUpdate();
} catch (SQLException e) {
System.out.println(e.getMessage());
} finally {
System.out.println("my stm is closed : " + stm.isClosed());
if (stm != null)
stm.close();
if (c != null)
c.close();
}
the delete is executed fine. Then I want to check how many records were deleted from the previous delete: So I call this method:
public int countDeletesRecords()
throws SQLException, ClassNotFoundException {
Connection c = null;
PreparedStatement stm = null;
sq = "SELECT changes() as \"deletedRows\" ";
int deletedRows=-1;
try {
Class.forName(typeDB);
c = DriverManager.getConnection(path);
stm = c.prepareStatement(sq);
ResultSet rs = stm.executeQuery();
if (rs.next()) {
deletedRows = rs.getInt("deletedRows");
}
} catch (SQLException e) {
System.out.println(e.getMessage());
} finally {
System.out.println("my stm is closed : " + stm.isClosed());
if (stm != null)
stm.close();
if (c != null)
c.close();
}
return deletedRows; //I get 0..
}
and I get 0, while 1 records where deleted.

While this does not directly answer the question an alternative, simpler, approach would capture the return value of executeUpdate(), that returns the number of affected (in this case, deleted) rows:
final int deletedRowCount = stm.executeUpdate();

The documentation says:
This function returns the number of rows modified, inserted or deleted by the most recently completed INSERT, UPDATE or DELETE statement on the database connection
You are creating a new database connection in which no DELETE statement was ever executed.

Related

Update a column if row exists, and insert row if it doesn't

I have a table INVENTORY with 2 columns [product(primary key) - quantity]. I want to insert to this table a product with its quantity.
public boolean insertPackage(String product, int quantity)
throws SQLException, ClassNotFoundException {
System.out.println("Insert product to Invetory");
boolean flag=false;
sq = "INSERT INTO INVENTORY VALUES (?, ?)";
try {
Class.forName(typeDB);
c = DriverManager.getConnection(path);
stm = c.prepareStatement(sq);
PreparedStatement stm = c.prepareStatement(sq);
stm.setString(1, product);
stm.setInt(2, quantity);
int rowsAffected = stm.executeUpdate();
} catch (SQLException e) {
//There is already a same product in the Inventory
flag = true;
System.out.println(e.getMessage());
} finally {
if (stm != null)
stm.close();
if (c != null)
c.close();
}
return flag; //if the flag is true, then execute insert.
}
If it returns true, then I search for this product, retrieve the quantity and then update the table with the new quantity. I am wondering if this way I thought, is a good way to check how to perform the insertion or there is a better one.
In your particular case the easiest solution would be to use SQLite's INSERT OR REPLACE syntax, like so:
public static void main(String[] args) {
String connectionURL = "jdbc:sqlite:"; // in-memory database
try (Connection conn = DriverManager.getConnection(connectionURL)) {
// set up test data
try (Statement st = conn.createStatement()) {
st.execute("CREATE TABLE INVENTORY (product VARCHAR(10) PRIMARY KEY, quantity INT)");
st.execute("INSERT INTO INVENTORY (product, quantity) VALUES ('one', 123)");
}
System.out.println("Initial state:");
dumpTable(conn);
// real code starts here
String sql = "INSERT OR REPLACE INTO INVENTORY (product, quantity) VALUES (?, ?)";
try (PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, "two"); // product is new, so it will insert
ps.setInt(2, 234);
ps.executeUpdate();
System.out.println();
System.out.println("First change:");
dumpTable(conn);
ps.setString(1, "one"); // product already exists, so it will replace
ps.setInt(2, 999);
ps.executeUpdate();
System.out.println();
System.out.println("Second change:");
dumpTable(conn);
}
} catch (Exception e) {
e.printStackTrace(System.err);
}
}
private static void dumpTable(Connection conn) throws SQLException {
try (
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT product, quantity FROM INVENTORY ORDER BY product")) {
while (rs.next()) {
System.out.printf(
"product \"%s\" - quantity: %d%n",
rs.getString("product"),
rs.getInt("quantity"));
}
}
}
However, INSERT OR REPLACE in SQLite is really just a DELETE followed by INSERT, so another solution would be to try and do the UPDATE first, then do an INSERT if the UPDATE doesn't affect any rows. (That might be more efficient if you tend to be doing more updates than inserts.)
public static void main(String[] args) {
String connectionURL = "jdbc:sqlite:"; // in-memory database
try (Connection conn = DriverManager.getConnection(connectionURL)) {
// set up test data
try (Statement st = conn.createStatement()) {
st.execute("CREATE TABLE INVENTORY (product VARCHAR(10) PRIMARY KEY, quantity INT)");
st.execute("INSERT INTO INVENTORY (product, quantity) VALUES ('one', 123)");
}
System.out.println("Initial state:");
dumpTable(conn);
// real code starts here
updateQuantity("two", 234, conn);
System.out.println();
System.out.println("First update:");
dumpTable(conn);
updateQuantity("one", 999, conn);
System.out.println();
System.out.println("Second update:");
dumpTable(conn);
} catch (Exception e) {
e.printStackTrace(System.err);
}
}
private static void updateQuantity(String theProduct, int newQuantity, Connection conn) throws SQLException {
int rowsAffected;
try (PreparedStatement psUpdate = conn.prepareStatement("UPDATE INVENTORY SET quantity=? WHERE product=?")) {
psUpdate.setInt(1, newQuantity);
psUpdate.setString(2, theProduct);
rowsAffected = psUpdate.executeUpdate();
}
if (rowsAffected == 0) {
try (PreparedStatement psInsert = conn.prepareStatement("INSERT INTO INVENTORY (product, quantity) VALUES (?, ?)")) {
psInsert.setString(1, theProduct);
psInsert.setInt(2, newQuantity);
psInsert.executeUpdate();
}
}
}
private static void dumpTable(Connection conn) throws SQLException {
try (
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT product, quantity FROM INVENTORY ORDER BY product")) {
while (rs.next()) {
System.out.printf(
"product \"%s\" - quantity: %d%n",
rs.getString("product"),
rs.getInt("quantity"));
}
}
}
In both cases we see:
Initial state:
product "one" - quantity: 123
First update:
product "one" - quantity: 123
product "two" - quantity: 234
Second update:
product "one" - quantity: 999
product "two" - quantity: 234
This is not a good way to check if a product exists because:
-There are many other things that can go wrong ( a lot of different SQLExceptions, not only PK violation ) and you will end up with a true flag.
-You should not use exceptions for something that is normal to happen.
-Throwing and catching an exception is slow.
Try this:
1) select from INVENTORY by product using count:
select count(*) from INVENTORY where product = ?
2) if the count is equal to 0 then execute the insert
else increment the quantity.

SQLite test if record exists

I am struggling with testing if there is specific data in my SQLite database.
The method accepts a subject code, person id, and a table name. I am 100% sure those 3 things are correct.
What this should do is try to select a record. If the record can be selected return -1, otherwise return 0.
My problem is the datareader does not seem to be reading any records, when there is records in my database.
public int TestIfExists(string subID, string personID, string table)
{
_sqlConnection = new SQLiteConnection(_conStr);
bool dataRead = false;
int rc = 0;
try
{
string selectQuery = "SELECT * FROM " + table + " WHERE PersonID = '" +
personID + "' AND SubjectCode = '" + subID + "'";
_sqlConnection.Open();
SQLiteCommand sqlCommand = new SQLiteCommand(selectQuery, _sqlConnection);
IDataReader idr = sqlCommand.ExecuteReader();
dataRead = idr.Read();
if (dataRead == true)
{
rc = -1;
}//end if
else
{
rc = 0;
}//end else
idr.Close(); // Closed IDataReader
}//end try
catch (SQLiteException sqlEx) // Catch SQLiteException
{
MessageBox.Show(sqlEx.ToString());
throw new DataStoreError(sqlEx.Message);
}//end catch
catch (Exception ex)
{
throw ex;
}//end catch
finally
{
_sqlConnection.Close();
}//end finally
return rc; //Single return
}
When you are trying to see if it exists or no, you can do a
SELECT Count(*) FROM Table WHERE (...)
and this way 0 would means doesn't exists, other wise yes.

Unable to update DB by form data

please give me advice! I get form data in servlet and try to update the database, but it doesn't works. There is connection with database (without servlet code any data is properly added in db), but no any exception are thrown. The servlet get parameters - they are available in JSP by EL-expressions. I tried to update the db simply by statement, without using preparedStatement but it didn't help. Here it is the code:
public class ServletClass extends HttpServlet {
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
DBConn dbConn = new DBConn();
String number = req.getParameter("number");
String amount = req.getParameter("amount");
String date = req.getParameter("date");
ArrayList list = dbConn.returnList(number, amount, date);
req.setAttribute("attr", list);
RequestDispatcher requestDispatcher = req.getRequestDispatcher("index.jsp");
requestDispatcher.forward(req, resp);
}
}
public class DBConn {
public ArrayList<InvoicesBean> returnList(String number, String amount, String date) {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
ArrayList<InvoicesBean> beanList = new ArrayList<InvoicesBean>();
PreparedStatement preparedStatement = null;
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/ved", "root", "1111");
statement = connection.createStatement();
preparedStatement = connection.prepareStatement("insert into invoices values(?, ?, ?);");
preparedStatement.setString(1, number);
preparedStatement.setString(2, amount);
preparedStatement.setString(3, date);
preparedStatement.executeUpdate();
resultSet = statement.executeQuery("SELECT * FROM invoices;");
while (resultSet.next()){
InvoicesBean invoicesBean = new InvoicesBean();
invoicesBean.setNumber(resultSet.getString("number"));
invoicesBean.setAmount(resultSet.getString("amount"));
invoicesBean.setDate(resultSet.getString("date"));
beanList.add(invoicesBean);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (resultSet != null) resultSet.close();
if (statement != null) statement.close();
if (connection != null) connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return beanList;
}
}
InvoiceBean-class is just a standard bean class with getters/setters
invoicesBean.setNumber(resultSet.getString("number"));
invoicesBean.setAmount(resultSet.getString("amount"));
invoicesBean.setDate(resultSet.getString("date"));
You can not have the database column names as 'number' or 'date'. they are reserved.
check the column names again.
for checking if this is the error, you can replace the column names by column numbers 1,2,3.

Datatype mismatch for blob type blackberry

I have an exception that Datatype mismatch in this line
byte[] _data = (byte[])row.getBlobBytes(1);
and in the table I have the type of column 2 is BLOB.
public static UrlRsc getContentUrl(String name) {
UrlRsc elementRsc = null;
try {
Statement statement = DB
.createStatement("SELECT * FROM table where"
+ " Name='"
+ name + "'");
statement.prepare();
Cursor cursor = statement.getCursor();
Row row;
while (cursor.next()) {
row = cursor.getRow();
byte[]_data;
_data = row.getBlobBytes(1);
}
statement.close();
cursor.close();
} catch (DatabaseException dbe) {
System.out.println(dbe.toString());
} catch (DataTypeException dte) {
System.out.println(dte.toString());
}
return elementRsc;
}
Can any one help me ?
Hi i am using following code for save image in my local database and i got success. i just posted my 3 methods
Note: When i am inserting image into data base i changed that image in byte array then only i can save into that table
1)Table creation 2) table insertion 3)image retrieving from table
ContactImage_table creation
public ContactImageTableCreation(){
try{
Statement stmt=DATABASE.createStatement("create table if not exists 'ContactImage_table'(ID 'TEXT',image 'blob',NodeId 'TEXT')");
stmt.prepare();
stmt.execute();
stmt.close();
}catch(Exception e){
System.out.println(e.getMessage());
}
}
Insert data into ContactImage_table
public void ContactImageTableInsertion(){
try{
Statement st=DATABASE.createStatement("insert into ContactImage_table (ID,Image,NodeId)values(?,?,?)");
st.prepare();
st.bind(1, "101");
st.bind(2, BYTE_ARRY);
st.bind(3,"103");
st.execute();
st.close();
}catch (Exception e) {
System.out.println(e.getMessage());
}
}
Retrieving data from ContactImage_table
public ContactImageTableDataRetriving(){
try{
Statement st=DATABASE.createStatement("select * from ContactImage_table");
st.prepare();
Cursor c=st.getCursor();
Row r;
int i=0;
while(c.next()){
r=c.getRow();
i++;
// ContactImageObject is a wrapper class for data handling
contactImageObj=new ContactImageObject();
contactImageObj.setId(r.getString(0));
byte[] decoded=r.getBlobBytes(1);
EncodedImage fullImage = EncodedImage.createEncodedImage(decoded, 0, decoded.length);
Bitmap b=fullImage.getBitmap();
contactImageObj.setImage(b);
// System.out.println("Successfully retrived");
if(i==0){
// System.out.println("No Records");
}
}
st.close();
}catch (Exception e) {
// System.out.println(e.getMessage());
}
}
just cross check your code with this code snippet hope you will get resolve all the best

SQLite keep expanding

I'm new to the blackberry development and to this site. right now, i'm working on an app that retrieve data from a json service. In my app I should parse the data into a database and save it in four tables. I already parsed the data and I was successful able to create the database and add the first and the second tables.
The problem that I'm facing right now is, the second table in my data base keep expanding. I checked the database in the sql browser and I discovered that everytime I click on the app icon it adds the 700 rows to the table again.(ex. 700 becomes 1400) .
(only to the second table, the first table works so fine).
Thank you in advance
This is my code:
public void parseJSONResponceInBB(String jsonInStrFormat)
{
try {
JSONObject json = newJSONObject(jsonInStrFormat);
JSONArray jArray = json.getJSONArray("tables");
for (inti = 0; i < jArray.length(); i++) {
//Iterate through json array
JSONObject j = jArray.getJSONObject(i);
if (j.has("Managers")) {
add(new LabelField("Managers has been added to the database"));
JSONArray j2 = j.getJSONArray("Managers");
for (intk = 0; k < j2.length(); ++k) {
JSONObject MangersDetails = j2.getJSONObject(k);
if (MangersDetails.has("fName")) {
try {
URI myURI =
URI.create
("file:///SDCard/Databases/SQLite_Guide/"
+ "MyTestDatabase.db");
d = DatabaseFactory.openOrCreate(myURI);
Statement st =
d.createStatement
("CREATE TABLE Managers ( "
+ "fName TEXT, " +
"lName TEXT, " + "ID TEXT," + "Type TEXT )");
st.prepare();
st.execute();
st.close();
d.close();
}
catch(Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
try {
URI myURI =
URI.create
("file:///SDCard/Databases/SQLite_Guide/"
+ "MyTestDatabase.db");
d = DatabaseFactory.open(myURI);
Statement st =
d.createStatement
("INSERT INTO Managers(fName, lName, ID, Type) "
+ "VALUES (?,?,?,?)");
st.prepare();
for (intx = 0; x < j2.length(); x++) {
JSONObject F = j2.getJSONObject(x);
//add(new LabelField ("f"));
st.bind(1, F.getString("fName"));
st.bind(2, F.getString("lName"));
st.bind(3, F.getString("ID"));
st.bind(4, F.getString("Type"));
st.execute();
st.reset();
}
d.close();
}
catch(Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
}
}
}
catch(JSONException e) {
e.printStackTrace();
}
}
//Owners method
public voidparseJSONResponceInBB1(String jsonInStrFormat)
{
try {
JSONObject json = newJSONObject(jsonInStrFormat);
JSONArray jArray = json.getJSONArray("tables");
for (inti = 0; i < jArray.length(); i++) {
//Iterate through json array
JSONObject j = jArray.getJSONObject(i);
if (j.has("Owners")) {
add(new LabelField("Owners has been added to the database"));
JSONArray j2 = j.getJSONArray("Owners");
for (intk = 0; k < j2.length(); ++k) {
JSONObject OwnersDetails = j2.getJSONObject(k);
if (OwnersDetails.has("fName")) {
try {
Statement st =
d.createStatement
("CREATE TABLE Owners ( "
+ "fName TEXT, " +
"lName TEXT, " + "ID TEXT," + "Type TEXT )");
st.prepare();
st.execute();
st.close();
d.close();
}
catch(Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
try {
Statement st =
d.createStatement
("INSERT INTO Owners(fName, lName, ID, Type) "
+ "VALUES (?,?,?,?)");
st.prepare();
for (intx = 0; x < j2.length(); x++) {
JSONObject F = j2.getJSONObject(x);
//add(new LabelField ("f"));
st.bind(1, F.getString("fName"));
st.bind(2, F.getString("lName"));
st.bind(3, F.getString("ID"));
st.bind(4, F.getString("Type"));
st.execute();
st.reset();
}
d.close();
}
catch(Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
}
}
}
catch(JSONException e) {
e.printStackTrace();
}
}
It depends on what your goals are here. If you want to replace the data in the database each time the json query runs, you should add a sqlite command to remove all the existing rows with the newly fetched ones coming in via JSON.
If you just want to keep certain types of records unique, you should add an index to the sqlite table. The 'ID' column is a likely candidate for this. You'll have to do some experiments to make sure a conflict is handled correctly - it may abort the entire transaction. "INSERT OR REPLACE" is useful in that situation.

Resources