SQLite Comparing tables in Android - java

Is there any method to compare tables (with the same properties of course) and return true if they are the same and false if not? Thanks.

Not directly but it is realtively easy.
That is sqlite stores the SQL used to define the tables in the table sqlite_master (the schema).
For the simplest comparision of SQL to SQL (for column definitions) then you could use the following SQL:-
WITH tablenames(table1,table2) AS (SELECT 'table1' /*<<<<< change accordingly */,'table2' /*<<<<< change accordingly*/)
SELECT
COALESCE(
(SELECT substr(sql,instr(sql,'(')) FROM sqlite_master WHERE name = (SELECT table1 FROM tablenames)) =
(SELECT substr(sql,instr(sql,'(')) FROM sqlite_master WHERE name = (SELECT table2 FROM tablenames))
,0)
;
In Android this could be done using (within a database helper ) :-
public boolean compareTable(String table1, String table2) {
SQLiteDatabase db = this.getWritableDatabase();
String result_column = "result";
boolean rv = false;
Cursor csr = db.rawQuery("WITH tablenames(table1,table2) AS (SELECT ? ,? )" +
"SELECT " +
"COALESCE(" +
"(SELECT substr(sql,instr(sql,'(')) FROM sqlite_master WHERE name = (SELECT table1 FROM tablenames)) =" +
"(SELECT substr(sql,instr(sql,'(')) FROM sqlite_master WHERE name = (SELECT table2 FROM tablenames))" +
",0) " +
"AS " + result_column +
";",new String[]{table1,table2});
if (csr.moveToFirst()) {
rv = (csr.getInt(csr.getColumnIndex(result_column)) > 0);
}
csr.close();
return rv;
}
Note this will consider the slightest difference in the SQL as failing the comparison
Example
The Database Helper DatabaseHelper.java
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DBNAME = "mydb";
public static final int DBVERSION = 1;
public static final String TABLE = "htmlstore";
public static final String IDCOLUMN = BaseColumns._ID;
public static final String HTMLCOLUMN = "html";
public static final String TABLE2 = "otherstore";
public static final String TABLE3 = "storeother";
SQLiteDatabase db;
public DatabaseHelper(Context context) {
super(context, DBNAME, null, DBVERSION);
db = this.getWritableDatabase();
}
#Override
public void onCreate(SQLiteDatabase db) {
String crt_htmlstore_table = "CREATE TABLE IF NOT EXISTS " + TABLE + "(" +
IDCOLUMN + " INTEGER PRIMARY KEY," +
HTMLCOLUMN + " TEXT" +
")";
db.execSQL(crt_htmlstore_table);
String crt_otherstore_table = "CREATE TABLE IF NOT EXISTS " + TABLE2 + "(" +
IDCOLUMN + " INTEGER PRIMARY KEY," +
HTMLCOLUMN + " TEXT" +
")";
db.execSQL(crt_otherstore_table);
String crt_storeother_table = "CREATE TABLE IF NOT EXISTS " + TABLE3 + "(" +
HTMLCOLUMN + " TEXT, " +
IDCOLUMN + " INTEGER, " +
" PRIMARY KEY(" + IDCOLUMN + ")" +
")";
db.execSQL(crt_storeother_table);
}
public long insert(String html) {
ContentValues cv = new ContentValues();
cv.put(HTMLCOLUMN,html);
return db.insert(TABLE,null,cv);
}
public String getHTML(long id) {
String rv = "";
Cursor csr = db.query(TABLE,new String[]{HTMLCOLUMN},IDCOLUMN+"=?",new String[]{String.valueOf(id)},null,null,null);
if (csr.moveToFirst()) {
rv = csr.getString(csr.getColumnIndex(HTMLCOLUMN));
}
csr.close();
return rv;
}
public boolean compareTable(String table1, String table2) {
SQLiteDatabase db = this.getWritableDatabase();
String result_column = "result";
boolean rv = false;
Cursor csr = db.rawQuery("WITH tablenames(table1,table2) AS (SELECT ? ,? )" +
"SELECT " +
"COALESCE(" +
"(SELECT substr(sql,instr(sql,'(')) FROM sqlite_master WHERE name = (SELECT table1 FROM tablenames)) =" +
"(SELECT substr(sql,instr(sql,'(')) FROM sqlite_master WHERE name = (SELECT table2 FROM tablenames))" +
",0) " +
"AS " + result_column +
";",new String[]{table1,table2});
if (csr.moveToFirst()) {
rv = (csr.getInt(csr.getColumnIndex(result_column)) > 0);
}
csr.close();
return rv;
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
Note that effectively the 3 tables are all the same (BUT the 3rd table differs in the SQL used to generate the column definitions and will thus be considered different)
COALESCE is used to convert a null (no such table(s) in sqlite_master) to 0 (false)
The invoking code MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DatabaseHelper databaseHelper = new DatabaseHelper(this);
Log.d("TABLECOMPARE"," Result = " + String.valueOf(databaseHelper.compareTable(DatabaseHelper.TABLE,DatabaseHelper.TABLE2)));
Log.d("TABLECOMPARE"," Result = " + String.valueOf(databaseHelper.compareTable(DatabaseHelper.TABLE2,DatabaseHelper.TABLE3)));
Log.d("TABLECOMPARE"," Result = " + String.valueOf(databaseHelper.compareTable(DatabaseHelper.TABLE,DatabaseHelper.TABLE3)));
Log.d("TABLECOMPARE"," Result = " + String.valueOf(databaseHelper.compareTable(DatabaseHelper.TABLE,DatabaseHelper.TABLE)));
}
}
Result :-
2020-01-14 07:23:29.624 D/TABLECOMPARE: Result = true
2020-01-14 07:23:29.625 D/TABLECOMPARE: Result = false
2020-01-14 07:23:29.625 D/TABLECOMPARE: Result = false
2020-01-14 07:23:29.626 D/TABLECOMPARE: Result = true
i.e.
Table1 and Table2 are considered the same
Table2 and Table3 are considered different
Table1 and Table3 are considered different
Table1 is considered the same as table 1.

Related

How to get other column with onItemClickListener in ListView

I am working on a Shopping list where you can click on the item in the ListView and a dialog comes up. There you can modify the product name. It works fine, but now i am trying to add details.
Adding to database already works. It is in the third column but now I cant get it out with the onItemClickListener.
Get Data from the second column works fine, so the the product is working fine with ItemOnClick.
I already tried a couple of codes but didnt find a solution.
OnItemClick:
lvProducts.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
try {
//DB*********************************
String name = parent.getItemAtPosition(position).toString();
Log.d(TAG, "onItemClick: You Clicked on " + name);
Cursor data = myDB.getItemID(name);
int itemID = -1;
while (data.moveToNext()){
itemID = data.getInt(0);
}
if (itemID > -1){
Log.d(TAG, "onItemClick: The ID is " + itemID);
Intent editScreenIntent = new Intent();
editScreenIntent.putExtra("id",itemID);
editScreenIntent.putExtra("name",name);
selectedID = editScreenIntent.getIntExtra("id",-1);
selectedName = editScreenIntent.getStringExtra("name");
}
showInputBox(arrayList.get(position), position);
} catch (Exception e) {
Toast.makeText(ShoppingActivity.this, "Error#666", Toast.LENGTH_SHORT).show();
}
}
});
DatabaseHelper:
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String TABLE_NAME = "myList_data";
public static final String COL1 = "ID";
public static final String COL2 = "ITEM1";
public static final String COL3 = "ITEM2";
public DatabaseHelper(Context context){
super(context, TABLE_NAME, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
String createTable = "CREATE TABLE " + TABLE_NAME + " (ID INTEGER PRIMARY KEY AUTOINCREMENT, " + COL2 + " TEXT, " + COL3 + " TEXT )";
db.execSQL(createTable);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS "+ TABLE_NAME);
onCreate(db);
}
public boolean addData(String item, String detail){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL2,item);
contentValues.put(COL3, detail);
long result = db.insert(TABLE_NAME,null,contentValues);
if (result == -1){
return false;
}else {
return true;
}
}
public Cursor getData(){
SQLiteDatabase db = this.getWritableDatabase();
String query = "SELECT * FROM " + TABLE_NAME;
Cursor data = db.rawQuery(query, null);
return data;
}
public Cursor getItemID(String name){
SQLiteDatabase db = this.getWritableDatabase();
//String query = "SELECT "+ COL1 + " FROM " + TABLE_NAME + " WHERE " + COL2 + " = '" + name + "'";
Cursor data = db.rawQuery("SELECT * FROM " + TABLE_NAME,null);
//Cursor data = db.rawQuery(query, null);
return data;
}
/**
* Updates the name field
* #param newName
* #param id
* #param oldName
*/
public void updateName(String newName,int id,String oldName){
SQLiteDatabase db = this.getWritableDatabase();
String query = "UPDATE " + TABLE_NAME + " SET " + COL2 + " = '" + newName + "' WHERE " + COL1 + " = '" + id + "'" + " AND " + COL2 + " = '" + oldName + "'";
db.execSQL(query);
}
public void deleteName(int id, String name){
SQLiteDatabase db = this.getWritableDatabase();
String query = "DELETE FROM " + TABLE_NAME + " WHERE " + COL1 + " = '" + id + "'" + " AND " + COL2 + " = '" + name + "'";
db.execSQL(query);
}
public void deleteAll(){
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_NAME,null,null);
String query =("DELETE FROM " + TABLE_NAME);
db.execSQL(query);
}
}
Try :-
int itemID = -1;
String item3 = ""; //<<<<<<<<<< ADDED
while (data.moveToNext()){
itemID = data.getInt(0);
item3 = data.getString(data.getColumnIndex(DatabaseHelper.COL3)); //<<<<<<<<<< ADDED
}
Note using getColumnIndex and the column name is more flexible and less prone to mis-calculation of offsets. You may wish to consider changing itemID = data.getInt(0); to itemID = data.getInt(data.getColumnIndex(DatabaseHelper.COL1));
Your getItemId method will, as it stands get all rows not just the row that has the name. You may wish to change from :-
public Cursor getItemID(String name){
SQLiteDatabase db = this.getWritableDatabase();
//String query = "SELECT "+ COL1 + " FROM " + TABLE_NAME + " WHERE " + COL2 + " = '" + name + "'";
Cursor data = db.rawQuery("SELECT * FROM " + TABLE_NAME,null);
//Cursor data = db.rawQuery(query, null);
return data;
}
to :-
public Cursor getItemID(String name){
SQLiteDatabase db = this.getWritableDatabase();
return db.query(TABLE_NAME,null,COL2+"=?",new String[]{name},null,null,null);
}
Note the above is in-principle code. It has not been tested or run and may therefore have some errors.

Using Android studio and my application force closes when i click a button [duplicate]

This question already has answers here:
Unfortunately MyApp has stopped. How can I solve this?
(23 answers)
Closed 3 years ago.
Hi I'm making a bill splitting app in android studio 3.3. I've made a database with sqlite and it stores a product's name and cost. As I am trying to get the total cost of the input from the database and store it in a text view the app closes. I've came to the conclusion that the problem is located in the getTotal() method in MyDBHandler.java
public class MyDBHandler extends SQLiteOpenHelper{
private static final int DATABASE_VERSION = 6;
private static final String DATABASE_NAME = "productDB.db";
public static final String TABLE_PRODUCTS = "products";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_PRODUCTNAME = "productname";
public static final String COLUMN_PRODUCTCOST = "productcost";
//We need to pass database information along to superclass
public MyDBHandler(Context context, String name,
SQLiteDatabase.CursorFactory factory, int version) {
super(context, DATABASE_NAME, factory, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
String query = "CREATE TABLE " + TABLE_PRODUCTS + "(" +
COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COLUMN_PRODUCTNAME + " TEXT " + "," +
COLUMN_PRODUCTCOST + " INTEGER " +
");";
db.execSQL(query);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_PRODUCTS);
onCreate(db);
}
//Add a new row to the database
public void addProduct(Products product){
ContentValues values = new ContentValues();
values.put(COLUMN_PRODUCTNAME, product.get_productname());
values.put(COLUMN_PRODUCTCOST, product.get_productcost());
SQLiteDatabase db = getWritableDatabase();
db.insert(TABLE_PRODUCTS, null, values);
db.close();
}
//Delete a product from the database
public void deleteProduct(String productName){
SQLiteDatabase db = getWritableDatabase();
db.execSQL("DELETE FROM " + TABLE_PRODUCTS + " WHERE " +
COLUMN_PRODUCTNAME + "=\"" + productName + "\";");
}
//get the total sum of teh Product_Cost column
//
// TODO: fix this method to display total
// NOTE: THIS IS YOUR PROBLEM
//
//
public int GetTotal(){
int temp;
SQLiteDatabase db = getWritableDatabase();
String query = " SELECT SUM(COLUMN_PRODUCTCOST) FROM " + TABLE_PRODUCTS + ";";
Cursor cursor = db.rawQuery(query , null);
if (cursor.moveToFirst()) {
temp = cursor.getInt(0);
}
else return 0;
cursor.close();
return temp;
}
// converts the elements in the database to a string so you can print the database out.
public String databaseToString(){
String dbString = "";
SQLiteDatabase db = getWritableDatabase();
String query = "SELECT * FROM " + TABLE_PRODUCTS + " WHERE 1";// why not leave out the WHERE clause?
//Cursor points to a location in your results
Cursor recordSet = db.rawQuery(query, null);
//Move to the first row in your results
recordSet.moveToFirst();
//Position after the last row means the end of the results
while (!recordSet.isAfterLast()) {
// null could happen if we used our empty constructor
if (recordSet.getString(recordSet.getColumnIndex("productname")) != null) {
dbString += recordSet.getString(recordSet.getColumnIndex("productname"));
dbString += "\t $";
dbString += recordSet.getString(recordSet.getColumnIndex("productcost"));
dbString += "\n";
}
recordSet.moveToNext();
}
db.close();
return dbString;
}
}
public class MainActivity extends AppCompatActivity {
EditText userInput;
EditText userInputC;
TextView recordsTextView;
TextView Results;
MyDBHandler dbHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
userInput = (EditText) findViewById(R.id.user_Input);
userInputC = (EditText) findViewById(R.id.user_InputC);
recordsTextView = (TextView) findViewById(R.id.records_TextView);
Results = (TextView) findViewById(R.id.Results);
/* Can pass nulls because of the constants in the helper.
* the 1 means version 1 so don't run update.
*/
dbHandler = new MyDBHandler(this, null, null, 1);
printDatabase();
}
//Print the database
public void printDatabase(){
String dbString = dbHandler.databaseToString();
recordsTextView.setText(dbString);
userInput.setText("");
userInputC.setText("");
}
/*
//Add a product to the database
public void addButtonClicked(View view){
// dbHandler.add needs an object parameter.
int count = Integer.parseInt(Results.getText().toString());
int num = Integer.parseInt(userInputC.getText().toString());
count = count + num;
String temp = Results.getText().toString();
float temp1 = Float.parseFloat(temp);
//Results.setText(Integer.toString(count));
Results.setText(Float.toString(count));
Products product = new Products(userInput.getText().toString(), temp1);
dbHandler.addProduct(product);
//Results = ;
printDatabase();
}*/
#SuppressLint("SetTextI18n")
public void addButtonClicked(View view){
// dbHandler.add needs an object parameter.
int usersinput = Integer.parseInt(userInputC.getText().toString());
Products product = new Products(userInput.getText().toString(), usersinput);
int temp = dbHandler.GetTotal();
dbHandler.addProduct(product);
Results.setText(Integer.toString(temp));
printDatabase();
}
//Delete items
public void deleteButtonClicked(View view){
// dbHandler delete needs string to find in the db
String inputText = userInput.getText().toString();
dbHandler.deleteProduct(inputText);
printDatabase();
}
}
You should change :-
String query = " SELECT SUM(COLUMN_PRODUCTCOST) FROM " + TABLE_PRODUCTS + ";";
to be
String query = " SELECT SUM(" + COLUMN_PRODUCTCOST + ") FROM " + TABLE_PRODUCTS + ";";
Otherwise the query will fail as there is no column named COLUMN_PRODUCTCOST, instead you want the value when COLUMN_PRODUCTCOST is resolved (i.e. productcost), which is a column name.
You may also wish to consider using the query convenience method rather than using the rawQuery method.
Your code could then be :-
public int GetTotal(){
int temp;
SQLiteDatabase db = getWritableDatabase();
String[] columns = new String[]{"SELECT SUM(" + COLUMN_PRODUCTCOST + ")"}
Cursor cursor = db.query(TABLE_PRODUCTS,columns,null,null,null,null,null);
if (cursor.moveToFirst()) {
temp = cursor.getInt(0);
}
else temp = 0; //<<<<<<<<<< CHANGED not to return as the Cursor would not be closed.
cursor.close();
return temp;
}
Note this closes the Cursor even if there are no rows, which should be the case (you could apply this to your code that uses rawQuery).
This is a bad sql query:
String query = " SELECT SUM(COLUMN_PRODUCTCOST) FROM " + TABLE_PRODUCTS + ";"
Should it be
String query = " SELECT SUM(" + COLUMN_PRODUCTCOST + ") FROM " + TABLE_PRODUCTS + ";"

Paste comma separated list into EditText and store in SQLite TABLE on multiple rows

I'm wondering how to paste a comma separated list (test1,test2,test3,test4) in an EditText field and on clicking a button have it store in my SQLite Database Table with each one on it's own row. This would be ideal so that people with a big list (50-100) can mass insert data. Right now I have it to were it will insert a single name into my Table.
DatabaseHelper.java
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String TAG = "DatabaseHelper";
private static final String TABLE_NAME = "hashtag_table";
private static final String COL1 = "ID";
private static final String COL2 = "name";
#Override
public void onCreate(SQLiteDatabase db) {
String createTable = "CREATE TABLE " + TABLE_NAME + " (ID INTEGER PRIMARY KEY AUTOINCREMENT, " + COL2 +" TEXT)";
db.execSQL(createTable);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP IF TABLE EXISTS " + TABLE_NAME);
onCreate(db);
}
public DatabaseHelper(Context context) {
super(context, TABLE_NAME, null, 1);
}
/**
* Add data to the table
* #param item
* #return
*/
public boolean addData(String item) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL2, item);
Log.d(TAG, "addData: Adding " + item + " to " + TABLE_NAME);
long result = db.insert(TABLE_NAME, null, contentValues);
if (result == -1) {
return false;
} else {
return true;
}
}
/**
* Gets the data from the table
* #return
*/
public Cursor getData() {
SQLiteDatabase db = this.getWritableDatabase();
String query = "SELECT * FROM " + TABLE_NAME;
Cursor data = db.rawQuery(query, null);
return data;
}
/**
* Gets the ID from the table
* #param name
* #return
*/
public Cursor getItemID(String name) {
SQLiteDatabase db = this.getWritableDatabase();
String query = "SELECT " + COL1 + " FROM " + TABLE_NAME + " WHERE " + COL2 + " = '" + name + "'";
Cursor data = db.rawQuery(query,null);
return data;
}
/**
* Updates the name from the table
* #param newName
* #param id
* #param oldName
*/
public void updateName(String newName, int id, String oldName) {
SQLiteDatabase db = this.getWritableDatabase();
String query = "UPDATE " + TABLE_NAME + " SET " + COL2 + " = '" + newName + "' WHERE " + COL1 + " = '" + id + "'" + " AND " + COL2 + " = '" + oldName + "'";
Log.d(TAG, "updateName: query: " + query);
Log.d(TAG, "updateName: setting name to " + newName);
db.execSQL(query);
}
/**
* Deletes the name from the table
* #param id
* #param name
*/
public void deleteName(int id, String name) {
SQLiteDatabase db = this.getWritableDatabase();
String query = "DELETE FROM " + TABLE_NAME + " WHERE " + COL1 + " = '" + id + "'" + " AND " + COL2 + " = '" + name + "'";
Log.d(TAG, "deleteName: query: " + query);
Log.d(TAG, "deleteName: Deleting " + name + " from database.");
db.execSQL(query);
db.execSQL("UPDATE SQLITE_SEQUENCE SET seq = 0 WHERE NAME = '"+TABLE_NAME+"'");
}
}
ListView.java (where the editText and button is right now)
//Adds new hashtag to list and prompts if nothing is entered
btnAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String newEntry = editText.getText().toString();
if (editText.length() != 0) {
addData(newEntry);
editText.setText("");
} else {
toastMessage("you must put something in the text field");
}
}
});
populateListView();
}
/**
* Adds new data into the Database
* #param newEntry
*/
public void addData(String newEntry) {
boolean insertData = mDatabaseHelper.addData(newEntry);
if (insertData) {
toastMessage("Successfully inserted");
recreate();
} else {
toastMessage("Whoops, something went wrong");
}
}
The following is a pretty basic replacement for the addData that uses the String's split method to break the string into comma separated values and insert them :-
/**
* Add data to the table
*
* #param item
* #return
*/
public boolean addData(String item) {
String[] splitdata = item.split(","); //<<<<<<<<<< split the input string
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
boolean result = true;
db.beginTransaction(); //<<<<<<<<<< prepare to do in a single transaction
// Loop through each string inserting an entry into the database
for (String s : splitdata) {
contentValues.clear(); //<<<<<<<<<< clear any existing values to be safe
contentValues.put(COL2, s);
if (db.insert(TABLE_NAME, null, contentValues) < 1) {
result = false;
}
}
if (result) {
db.setTransactionSuccessful(); //<<<<<<<<<< only set the transaction successful if all inserts worked
}
db.endTransaction();
return result;
}
Note that this will roll back all inserts if there are any failed inserts and additionally return a false.
The above code is in principle code, it hasn't been tested or run and may therefore contains some errors.

android.database.CursorIndexOutOfBoundsException -- my cursor is empty

So I have been trying to query in my sqlite database for my android app. However, it seems like my cursor is not working like it is supposed too as I can get any results.
I know that I only have 3 items in my database, but what I put in my query are valid attributes for my 3 items stored. But there is still no result.
Below is my code for the query function and my database model.
// To get data from DB by querying the items selected
public String getData(int firstSelection, int secondSelection, int thirdSelection,
int fourthSelection, int fifthSelection)
{
SQLiteDatabase db = dbHelper.getWritableDatabase();
String firstSelectionStr, secondSelectionStr, thirdSelectionStr, fourthSelectionStr, fifthSelectionStr;
firstSelectionStr = Integer.toString(firstSelection);
secondSelectionStr = Integer.toString(secondSelection);
thirdSelectionStr = Integer.toString(thirdSelection);
fourthSelectionStr = Integer.toString(fourthSelection);
fifthSelectionStr = Integer.toString(fifthSelection);
//String[] columns = {DBHelper.UID,DBHelper.CNAME};
//Cursor cursor = db.query(DBHelper.TABLE_NAME,columns,null,null,null,null,null);
String selectQuery = "SELECT * FROM "+ DBHelper.TABLE_NAME + " WHERE " + DBHelper.FIRST_ATTRIBUTE + "=? "
+ " AND " + DBHelper.SECOND_ATTRIBUTE + "=? " + " AND " + DBHelper.THIRD_ATTRIBUTE + "=? " + " AND " + DBHelper.FOURTH_ATTRIBUTE + "=? "
+ " AND " + DBHelper.FIFTH_ATTRIBUTE + "=?";
Cursor cursor=db.rawQuery(selectQuery, new String[] {firstSelectionStr, secondSelectionStr, thirdSelectionStr,
fourthSelectionStr, fifthSelectionStr});
StringBuilder buffer = new StringBuilder();
cursor.moveToFirst();
if (cursor != null) {
int tresult = cursor.getCount();
// Append every data together
do {
//int cursorID = cursor.getInt(cursor.getColumnIndex(DBHelper.UID));
String chosenItem = cursor.getString(cursor.getColumnIndex(DBHelper.CNAME));
buffer.append(chosenItem + " ");
} while (cursor.moveToNext());
/*while (cursor.moveToNext())
{
//int cursorID = cursor.getInt(cursor.getColumnIndex(DBHelper.UID));
String chosenItem = cursor.getString(cursor.getColumnIndex(DBHelper.CNAME));
buffer.append(chosenItem + " ");
}*/
}
return buffer.toString();
}
static class DBHelper extends SQLiteOpenHelper
{
private static final String DATABASE_NAME = "CraftsAppDatabase.db"; // Database Name
private static final String TABLE_NAME = "CraftTools"; // Table Name
private static final String RESULT_TABLE = "Result"; // Table Name
private static final int DATABASE_Version = 1; // Database Version
private static final String UID="_id"; // Column I (Primary Key)
private static final String CNAME = "Craft_Name"; //Column II
private static final String RESULT = "Result_Name"; //Column II
private static final String FIRST_ATTRIBUTE = "First_Attribute"; //Column III
private static final String SECOND_ATTRIBUTE = "Second_Attribute"; //Column IV
private static final String THIRD_ATTRIBUTE = "Third_Attribute"; //Column V
private static final String FOURTH_ATTRIBUTE = "Fourth_Attribute"; //Column VI
private static final String FIFTH_ATTRIBUTE = "Fifth_Attribute"; //Column VII
private static final String CREATE_TABLE = "CREATE TABLE "+TABLE_NAME+
" ("+UID+" INTEGER PRIMARY KEY AUTOINCREMENT, "+CNAME+" VARCHAR(255)" +
", "+FIRST_ATTRIBUTE+" VARCHAR(255), "+SECOND_ATTRIBUTE+" VARCHAR(255)" +
", "+THIRD_ATTRIBUTE+" VARCHAR(255), "+FOURTH_ATTRIBUTE+" VARCHAR(255)" +
", "+FIFTH_ATTRIBUTE+" VARCHAR(255));";
private static final String CREATE_OTHER_TABLE = "CREATE TABLE "+RESULT_TABLE+
" ("+UID+" INTEGER PRIMARY KEY AUTOINCREMENT, "+RESULT+" VARCHAR(255));";
private static final String DROP_TABLE ="DROP TABLE IF EXISTS "+RESULT_TABLE;
private Context context;
public DBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_Version);
this.context=context;
}
/*public void deleteTable(SQLiteDatabase db) {
db = getWritableDatabase();
db.execSQL("DROP TABLE IF EXISTS CraftTools");
}*/
public void onCreate(SQLiteDatabase db) {
db.execSQL(DROP_TABLE);
db.execSQL(CREATE_OTHER_TABLE);
db.execSQL(CREATE_TABLE);
db.execSQL("INSERT INTO " + TABLE_NAME + "(Craft_Name, First_Attribute, Second_Attribute, Third_Attribute, Fourth_Attribute, Fifth_Attribute ) " +
"VALUES ('Landscape Drawing', '1', '4','8', '0', '0')");
db.execSQL("INSERT INTO " + TABLE_NAME + "(Craft_Name, First_Attribute, Second_Attribute, Third_Attribute, Fourth_Attribute, Fifth_Attribute ) " +
"VALUES ('Popsicle Sticks House', '2', '3','0', '0', '0')");
db.execSQL("INSERT INTO " + TABLE_NAME + "(Craft_Name, First_Attribute, Second_Attribute, Third_Attribute, Fourth_Attribute, Fifth_Attribute ) " +
"VALUES ('Sunset Painting', '4', '7','10', '0', '0')");
/*try {
db.execSQL(CREATE_TABLE);
} catch (Exception e) {
Message.message(context,""+e);
}*/
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//db.execSQL(DROP_TABLE);
onCreate(db);
if (newVersion > oldVersion) {
db.execSQL("ALTER TABLE CraftTools ADD COLUMN FIRST_ATTRIBUTE INTEGER DEFAULT 0");
db.execSQL("ALTER TABLE CraftTools ADD COLUMN SECOND_ATTRIBUTE INTEGER DEFAULT 0");
db.execSQL("ALTER TABLE CraftTools ADD COLUMN THIRD_ATTRIBUTE INTEGER DEFAULT 0");
db.execSQL("ALTER TABLE CraftTools ADD COLUMN FOURTH_ATTRIBUTE INTEGER DEFAULT 0");
db.execSQL("ALTER TABLE CraftTools ADD COLUMN FIFTH_ATTRIBUTE INTEGER DEFAULT 0");
//onCreate(db);
/*try {
Message.message(context,"OnUpgrade");
db.execSQL(DROP_TABLE);
onCreate(db);
}catch (Exception e) {
Message.message(context,""+e);*/
}
}
}
My logcat for the error is below this line. I am not sure why my result is empty or why nothing is being put in the buffer.
11-27 22:43:28.898 4502-4502/com.example.android.androidcraftsappprototype E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.androidcraftsappprototype, PID: 4502
android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
at android.database.AbstractCursor.checkPosition(AbstractCursor.java:468)
at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50)
at com.example.android.androidcraftsappprototype.DBAdapter.getData(DBAdapter.java:86)
at com.example.android.androidcraftsappprototype.SetupPage$2.onClick(SetupPage.java:118)
at android.view.View.performClick(View.java:6294)
at android.view.View$PerformClick.run(View.java:24770)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
i think your course return 0 item according to query..so you should write below condition
cursor.moveToFirst(); <--- instead of this
if(cursor.moveToFirst()){
// here all your code
}

Specific query error - SQLite Android

my problem is with very specific query. My SQLite datbase is only 1 table with 11 entries. It creates just fine, but upon execution of this piece of code it crashes. When I change the query to simply:
SELECT * FROM Items
Then it works fine, but I need more narrow results, therefore I modify with the "WHERE" clause. But then it crashes and the application stops. If I comment out the Cursor... it runs fine.
public int findPictureNumber(String itemtitle) {
String query = "SELECT nr_of_pics FROM Items WHERE ItemTitle = \"" + itemtitle + "\"";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
...
}
Where is the error? I can't seem to find it even after narrowing it down to those lines of code.
EDIT:
This is a method for adding an item to a database.
public void newItemFuro () {
MyDBHandler dbHandler = new MyDBHandler(this, null, null, 1);
String title = "Furo";
String author = "Fernando Brizio";//í
String category = "Decoracao";//çã
int date = 2012;
String type = "Taca";//ç
String country = "Portugal";
String colour = "Castanho/Cortica";//ç
String material = "Castanho/Cortica";//ç
boolean isFavourite = false;
String imgres = "furoo";
int nr_of_pics = 3;
Item item = new Item(title, author, category, date, type, country, colour, material, isFavourite, imgres, nr_of_pics);
dbHandler.addItem(item);
}
//helper for types
public static final String VARCHAR_TYPE = " VARCHAR(50)";
public static final String BOOL_TYPE = " BOOLEAN";
public static final String INT_TYPE = " INTEGER";
Here it creates the table:
public void onCreate(SQLiteDatabase db) {
String CREATE_ITEMS_TABLE = "CREATE TABLE " + TABLE_ITEMS +
"("
+ COLUMN_ENTRY_ID + INT_TYPE +" PRIMARY KEY AUTOINCREMENT,"
+ COLUMN_TITLE + VARCHAR_TYPE + ","
+ COLUMN_AUTHOR + VARCHAR_TYPE + ","
+ COLUMN_CATEGORY + VARCHAR_TYPE + ","
+ COLUMN_DATE + INT_TYPE + ","
+ COLUMN_TYPE + VARCHAR_TYPE + ","
+ COLUMN_COUNTRY + VARCHAR_TYPE + ","
+ COLUMN_COLOUR + VARCHAR_TYPE + ","
+ COLUMN_MATERIAL + VARCHAR_TYPE + ","
+ COLUMN_FAVOURITE + BOOL_TYPE + ","
+ COLUMN_IMGRES + VARCHAR_TYPE + ","
+ COLUMN_NUMBER_OF_PICS + INT_TYPE +
")";
db.execSQL(CREATE_ITEMS_TABLE);
}
Adding item:
public void addItem(Item item) {
ContentValues values = new ContentValues();
values.put(COLUMN_TITLE, item.getItemTitle());
values.put(COLUMN_AUTHOR, item.getAuthor());
values.put(COLUMN_CATEGORY, item.getCategory());
values.put(COLUMN_DATE, item.getDate());
values.put(COLUMN_TYPE, item.getType());
values.put(COLUMN_COUNTRY, item.getCountry());
values.put(COLUMN_COLOUR, item.getColour());
values.put(COLUMN_MATERIAL, item.getMaterial());
values.put(COLUMN_FAVOURITE, item.getFavourite());
values.put(COLUMN_IMGRES, item.getImgres());
values.put(COLUMN_NUMBER_OF_PICS, item.getNumberOfPics());
SQLiteDatabase db = this.getWritableDatabase();
db.insert(TABLE_ITEMS, null, values);
db.close();
}
Here full function for searching nr_of_pics:
public int findPictureNumber(String itemtitle) {
String query = "SELECT nr_of_pics FROM Items WHERE ItemTitle = '" + itemtitle + "'";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
int PicsNumber=0;
if (cursor.moveToFirst()) {
cursor.moveToFirst();
PicsNumber=Integer.parseInt(cursor.getString(0));
cursor.close();
return PicsNumber;
} else {
//wtf?
}
db.close();
return 0;
}
And the errors say as follows:
(1) table Items has no column named imgres
Error inserting colour=Castanho/Cortiça author=Fernando Brízio
imgres=furo category=Decoração title=Furo type=Taça date=2012
nr_of_pics=3 material=Castanho/Cortiça is_favourite=false
country=Portugal
android.database.sqlite.SQLiteException: table Items has no column named imgres (code 1): , while
compiling: INSERT INTO
Items(colour,author,imgres,category,title,type,date,nr_of_pics,material,is_favourite,country)
VALUES (?,?,?,?,?,?,?,?,?,?,?)
You do not give any exception but I think you have error in your SQL. You need to use ' instead of ".
Change your query as below.
String query = "SELECT nr_of_pics FROM Items WHERE ItemTitle = '" + itemtitle + "'";
It is clear that you don't have any column that named "imgres"!
You should modify your query
"INSERT INTO Items(colour,author,imgres,category,title,type,date,nr_of_pics,material,is_favourite,country)
VALUES (?,?,?,?,?,?,?,?,?,?,?)"

Categories

Resources