Before I get into describing by problem I'd like to point out I am aware of the other threads asking this question, however none for me have been able to solve my issue.
I've been working on a sharing app using the BumpAPI, which upon receiving the chunk, saves it to an SQLite database for retrieval in a list view activity, this is all working fine and the data is saved, however if the same text is sent twice it will be saved again and again and the list view will show this, from what I've read I need the 'UNIQUE' identifier? however being completely new to SQL I am at a loss with regards to achieving this, here is my DataHelper class which im using to create and add the entries, would anyone be kind enough to modify it or inform me of a possible solution?
Thanks very much
public class DataHelper {
private static final String DATABASE_NAME = "tags.db";
private static final int DATABASE_VERSION = 1;
private static final String TABLE_NAME = "TagTable";
private Context context;
private SQLiteDatabase db;
private SQLiteStatement insertStmt;
private static final String INSERT = "insert into "
+ TABLE_NAME + "(name) values (?)";
public DataHelper(Context context) {
this.context = context;
OpenHelper openHelper = new OpenHelper(this.context);
this.db = openHelper.getWritableDatabase();
this.insertStmt = this.db.compileStatement(INSERT);
}
public long insert(String name) {
this.insertStmt.bindString(1, name);
return this.insertStmt.executeInsert();
}
public void deleteAll() {
this.db.delete(TABLE_NAME, null, null);
}
public List<String> selectAll() {
List<String> list = new ArrayList<String>();
Cursor cursor = this.db.query(TABLE_NAME, new String[] { "name" },
null, null, null, null, "name desc");
if (cursor.moveToFirst()) {
do {
list.add(cursor.getString(0));
} while (cursor.moveToNext());
}
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
return list;
}
private static class OpenHelper extends SQLiteOpenHelper {
OpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_NAME + "(id INTEGER PRIMARY KEY, name TEXT)" + "text unique, " + "ON CONFLICT REPLACE");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
}
Add the unique keyword to the column.
db.execSQL("CREATE TABLE " + TABLE_NAME + "(id INTEGER PRIMARY KEY, name TEXT unique);
looks like you should first add unique index on Table Create statement
db.execSQL("CREATE TABLE " + TABLE_NAME + "(id INTEGER PRIMARY KEY, name TEXT)" + "**name** unique, " + "ON CONFLICT REPLACE");
it will prevent from having two entries with the same names
the second you could make select to check for existence of the data before making actually insert
Related
How can I add a new column or new table to the database that pre-populated (in the assets) using SQLiteAssetHelper.
I originally preload a simple table with 3 columns:
id
question
answer
Once installed the app, I need to add some columns that will be populated with user data, like marked as favorite, seen before, edited...
Also I need to add a new table that record the time of the study session, and last question seen.
here's my code:
import android.content.Context;
import com.readystatesoftware.sqliteasset.SQLiteAssetHelper;
public class DatabaseOpenHelper extends SQLiteAssetHelper {
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "mydatabase.db.sqlite";
public DatabaseOpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
}
and
public class DatabaseAccess {
private SQLiteOpenHelper openHelper;
private SQLiteDatabase database;
private static DatabaseAccess instance;
Hi you can use onUpgrade
public class OpenHelper extends SQLiteOpenHelper {
private final static int DB_VERSION = 2;
public TracksDB(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
//....
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion < 2) {
"create table session"
" (_id integer primary key autoincrement, " +
"date text not null, " +
"question text not null);";
db.execSQL(CREATE_TBL );
}
}
}
You can check database Version. If database version in app old version run create or alter query query.
SQLiteDatabase db = new Helper(context).getWritableDatabase();
if(db.getVersion()<2){
"create table session"
" (_id integer primary key autoincrement, " +
"date text not null, " +
"question text not null);";
db.execSQL(CREATE_TBL );
}
You must upgrade database version in asset folder.
I'm quite new to Android and I guess it's a stupid question but i'll be glad to recieve help. I've got a code in one activity which set a database to SQLite. In another activity I want to refer to this SQLite code in order to enter it into a json and send it to a remote server.
The problem is that it's not recognizing the variable from the other activity. here is the code which creates the data from the db into a string.
In this example I want to create an ArrayList from the db, but it couldnt find the set functions I developed or the table name. Am I missed something ? Here is the code of the ArrayList :
GpsPage.java
public class PersonsDatabaseHandler extends SQLiteOpenHelper {
//Database Name
private static final String DATABASE_NAME = "RecordsDB";
//Table names
private static final TABLE_RECORD = "record";
//Get all Persons
public ArrayList<Record> getAllPersons() {
ArrayList<Record> localList = new ArrayList<Record>();
String selectQuery = "SELECT * FROM " + TABLE_RECORD;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
//Loops through all rows and adds them to the local list
if(cursor.moveToFirst())
{
do {
//Get person information
Record record = new Record();
Record.setpLong(cursor.getString(0));
Record.setpLat(cursor.getString(1));
Record.setpAcc(cursor.getString(2));
Record.setpTime(cursor.getString(3));
//Add person to list
localList.add(record);
} while (cursor.moveToNext());
}
return localList;
}
}
And here are the codes from the two other java pages (activities), the first one define the get and set of the records :
Record.Java
package com.program.android.taskir;
public class Record {
//private variables
private int id;
private double pLong;
private double pLat;
private float pAcc;
private long pTime;
public Record(){}
// Empty constructor
// constructor
public Record( double pLong, double pLat, float pAcc, long pTime){
super();
this.pLong = pLong;
this.pLat= pLat;
this.pAcc= pAcc;
this.pTime= pTime;
}
#Override
public String toString() {
return "Record [id=" + id + ", Longtitude=" + pLong + ", Latitude=" + pLat + ", Accuracy" + pAcc + ", Time" +pTime
+ "]";
}
// getting ID
public int getID(){
return this.id;
}
// setting id
public void setID(int id){
this.id = id;
}
// getting pLong
public double getpLong(){
return this.pLong;
}
// setting pLong
public void setpLong(double pLong){
this.pLong = pLong;
}
// getting pLat
public double getpLat(){
return this.pLat;
}
// setting pLat
public void setpLat(double pLat){
this.pLat = pLat;
}
// getting pAcc
public float getpAcc(){
return this.pAcc;
}
// setting pAcc
public void setpAcc(float pAcc){
this.pAcc = pAcc;
}
// getting pTime
public long getpTime(){
return this.pTime;
}
// setting pTime
public void setpTime(long pTime){
this.pTime = pTime;
}
}
and the activity which creates the db :
MySQLiteHelper.java
package com.program.android.taskir;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import java.util.LinkedList;
import java.util.List;
public class MySQLiteHelper extends SQLiteOpenHelper {
// Database Version
private static final int DATABASE_VERSION = 1;
// Database Name
private static final String DATABASE_NAME = "RecordsDB";
public MySQLiteHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
// SQL statement to create record table
String CREATE_RECORD_TABLE = "CREATE TABLE RECORD ( " +
"id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"latitude TEXT NOT NULL, " +
"longtitude TEXT NOT NULL, " +
"accuracy TEXT NOT NULL, " +
"time TEXT NOT NULL )";
// create books table
db.execSQL(CREATE_RECORD_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Drop older books table if existed
db.execSQL("DROP TABLE IF EXISTS Records");
// create fresh record table
this.onCreate(db);
}
// Books table name
private static final String TABLE_RECORD = "record";
// Books Table Columns names
private static final String KEY_ID = "id";
private static final String KEY_LONG = "longtitude";
private static final String KEY_LAT = "latitude";
private static final String KEY_ACC = "accuracy";
private static final String KEY_TIME = "time";
private static final String[] COLUMNS = {KEY_ID, KEY_LONG, KEY_LAT, KEY_ACC, KEY_TIME};
public void addRecord(Record record) {
//for logging
Log.d("addBook", record.toString());
// 1. get reference to writable DB
SQLiteDatabase db = this.getWritableDatabase();
// 2. create ContentValues to add key "column"/value
ContentValues values = new ContentValues();
values.put(KEY_LONG, record.getpLong());
values.put(KEY_LAT, record.getpLat());
values.put(KEY_ACC, record.getpAcc());
values.put(KEY_TIME, record.getpTime());
// 3. insert
db.insert(TABLE_RECORD, // table
null, //nullColumnHack
values); // key/value -> keys = column names/ values = column values
// 4. close
db.close();
}
public Record getRecord(int id) {
// 1. get reference to readable DB
SQLiteDatabase db = this.getReadableDatabase();
// 2. build query
Cursor cursor =
db.query(TABLE_RECORD, // a. table
COLUMNS, // b. column names
" id = ?", // c. selections
new String[]{String.valueOf(id)}, // d. selections args
null, // e. group by
null, // f. having
null, // g. order by
null); // h. limit
// 3. if we got results get the first one
if (cursor != null)
cursor.moveToFirst();
// 4. build book object
Record record = new Record();
record.setID(Integer.parseInt(cursor.getString(0)));
record.setpLat(cursor.getDouble(1));
record.setpLong(cursor.getDouble(2));
record.setpAcc(cursor.getFloat(2));
record.setpTime(cursor.getLong(2));
//log
Log.d("getBook(" + id + ")", record.toString());
// 5. return book
return record;
}
public List<Record> getAllRecords() {
List<Record> records = new LinkedList<Record>();
// 1. build the query
String query = "SELECT * FROM " + TABLE_RECORD;
// 2. get reference to writable DB
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
// 3. go over each row, build book and add it to list
Record record = null;
if (cursor.moveToFirst()) {
do {
record = new Record();
record.setID(Integer.parseInt(cursor.getString(0)));
record.setpLat(cursor.getDouble(1));
record.setpLong(cursor.getDouble(2));
record.setpAcc(cursor.getFloat(2));
record.setpTime(cursor.getLong(2));
// Add book to books
records.add(record);
} while (cursor.moveToNext());
}
Log.d("getAllRecords()", record.toString());
// return books
return records;
}
public int UpdateRecords(Record record) {
// 1. get reference to writable DB
SQLiteDatabase db = this.getWritableDatabase();
// 2. create ContentValues to add key "column"/value
ContentValues values = new ContentValues();
values.put("Latitude", record.getpLat()); //
values.put("Longtitude", record.getpLong());
values.put("Accuracy", record.getpAcc());
values.put("Time", record.getpTime());
// 3. updating row
int i = db.update(TABLE_RECORD, //table
values, // column/value
KEY_ID + " = ?", // selections
new String[]{String.valueOf(record.getID())}); //selection args
// 4. close
db.close();
return i;
}
public void deleteRecords(Record record) {
// 1. get reference to writable DB
SQLiteDatabase db = this.getWritableDatabase();
// 2. delete
db.delete(TABLE_RECORD, //table name
KEY_ID + " = ?", // selections
new String[]{String.valueOf(record.getID())}); //selections args
// 3. close
db.close();
//log
Log.d("deleteBook", record.toString());
}
}
Thank you!
What you are looking for is a Bundle. It's used to pass data between activities. Take a look at What is a "bundle" in an Android application and you can understand how it's done.
I am trying to create a simple database but I receive this error:
09-09 12:42:14.750: E/AndroidRuntime(6971): Caused by: android.database.sqlite.SQLiteException: near "values": syntax error (code 1): , while compiling: create table values(_id integer primary key autoincrement, date text not null, screenTime integer not null );
I tried to look at other similar questions without finding a solution although I suspect my create statement to be incorrect but I am not sure.
Below is my code.
public class MySQLiteHelper extends SQLiteOpenHelper {
public static final String TABLE_VALUES = "values";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_DATE = "date";
public static final String COLUMN_SCREENTIME = "screenTime";
private static final String DATABASE_NAME = "screenTime.db";
private static final int DATABASE_VERSION = 1;
// Database creation sql statement
private static final String DATABASE_CREATE = "create table " + TABLE_VALUES
+ " ( " + COLUMN_ID + " integer primary key autoincrement, "
+ COLUMN_DATE + " text not null, "
+ COLUMN_SCREENTIME + " integer not null );";
public MySQLiteHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase database) {
database.execSQL(DATABASE_CREATE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(MySQLiteHelper.class.getName(),
"Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS " + TABLE_VALUES);
onCreate(db);
}
}
VALUES is a keyword.
You could quote it, but it would be a better idea to use a different name.
(Note: "values" is pretty much meaningless; every table has values in it.)
I have spent lots of time searching for the answer, but I couldn't find it.
I'm trying to use a SQLite database on my Android app, but when I try to add a new object with the db.insert(object), I get an error saying that my Primary Key is not UNIQUE.
What am I doing wrong?
SQLite Database:
public class SqlCadastro extends SQLiteOpenHelper{
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "contactsManager";
private static final String TABLE_MATERIAS = "Materias";
// Contacts Table Columns names
private static final String KEY_NOME = "Nome";
private static final String KEY_NOTA1 = "Tri1";
private static final String KEY_NOTA2 = "Tri2";
private static final String KEY_NOTA3 = "Tri3";
private static final String KEY_PRENOTA3 = "Est3Tri";
private static final String KEY_MA = "MA";
private static final String KEY_PREPFV = "EstPFV";
private static final String KEY_PFV = "PFV";
public SqlCadastro(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
// Creating Tables
#Override
public void onCreate(SQLiteDatabase db) {
String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_MATERIAS + "("
+ KEY_NOME + " TEXT UNIQUE," + KEY_NOTA1 + " FLOAT," + KEY_NOTA2 + " FLOAT," + KEY_PRENOTA3 + " FLOAT,"
+ KEY_NOTA3 + " FLOAT," + KEY_MA + " FLOAT," + KEY_PREPFV + " FLOAT, " + KEY_PFV + " FLOAT, PRIMARY KEY (" + KEY_NOME + ") ON CONFLICT IGNORE)" + ")";
db.execSQL(CREATE_CONTACTS_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_MATERIAS);
onCreate(db);
}
public void addMateria(Materias materia) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_NOME, materia.getNome());
values.put(KEY_NOTA1, Float.toString(materia.getNota1()));
values.put(KEY_NOTA2, Float.toString(materia.getNota2()));
values.put(KEY_PRENOTA3, Float.toString(materia.getPreNota3()));
values.put(KEY_NOTA3, Float.toString(materia.getNota3()));
values.put(KEY_MA, Float.toString(materia.getMA()));
values.put(KEY_PREPFV, Float.toString(materia.getPrePFV()));
values.put(KEY_PFV, Float.toString(materia.getPFV()));
// Inserting Row
db.insertOrThrow(TABLE_MATERIAS, null, values);
db.close(); // Closing database connection
}
}
The error log:
FATAL EXCEPTION: main
android.database.sqlite.SQLiteConstraintException: column Nome is not unique (code 19)
at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:775)
at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1469)
at android.database.sqlite.SQLiteDatabase.insertOrThrow(SQLiteDatabase.java:1365)
at com.testemedia.mediacp2.SqlCadastro.addMateria(SqlCadastro.java:68)
at com.testemedia.mediacp2.Cadastrar.onClick(Cadastrar.java:49)
at android.view.View.performClick(View.java:4084)
at android.view.View$PerformClick.run(View.java:16966)
at android.os.Handler.handleCallback(Handler.java:615)
error opening trace file: No such file or directory (2)
What am i doing wrong?
You are adding a row to a database table where your desired primary key is already used by another existing row. Either:
Use a separate column as the primary key, such as adding _ID INTEGER PRIMARY KEY AUTOINCREMENT, or
Make sure that everything you put in the Nome column is unique
The column Nome (KEY_NOME) is declared unique & as primary key (which implies unique).
Make sure, that there are no duplicate but unique values in Nome.
I am making an app for android with a SQLite Database that have only one table and two columns: one for names and the other for marks. Also, I can see the information of the database in a listview and I can add more elements to it. How can I make the average of the marks which are in the database? And how can I delete a row?
I paste my database helper
public class PersonDatabaseHelper {
private static final String TAG = PersonDatabaseHelper.class.getSimpleName();
// database configuration
// if you want the onUpgrade to run then change the database_version
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "mydatabase.db";
// table configuration
private static final String TABLE_NAME = "person_table"; // Table name
private static final String PERSON_TABLE_COLUMN_ID = "_id"; // a column named "_id" is required for cursor
private static final String PERSON_TABLE_COLUMN_NAME = "person_name";
private static final String PERSON_TABLE_COLUMN_PIN = "person_pin";
private DatabaseOpenHelper openHelper;
private SQLiteDatabase database;
// this is a wrapper class. that means, from outside world, anyone will communicate with PersonDatabaseHelper,
// but under the hood actually DatabaseOpenHelper class will perform database CRUD operations
public PersonDatabaseHelper(Context aContext) {
openHelper = new DatabaseOpenHelper(aContext);
database = openHelper.getWritableDatabase();
}
public void insertData (String aPersonName, String aPersonPin) {
// we are using ContentValues to avoid sql format errors
ContentValues contentValues = new ContentValues();
contentValues.put(PERSON_TABLE_COLUMN_NAME, aPersonName);
contentValues.put(PERSON_TABLE_COLUMN_PIN, aPersonPin);
database.insert(TABLE_NAME, null, contentValues);
}
public Cursor getAllData () {
String buildSQL = "SELECT * FROM " + TABLE_NAME;
Log.d(TAG, "getAllData SQL: " + buildSQL);
return database.rawQuery(buildSQL, null);
}
// this DatabaseOpenHelper class will actually be used to perform database related operation
private class DatabaseOpenHelper extends SQLiteOpenHelper {
public DatabaseOpenHelper(Context aContext) {
super(aContext, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
// Create your tables here
String buildSQL = "CREATE TABLE " + TABLE_NAME + "( " + PERSON_TABLE_COLUMN_ID + " INTEGER PRIMARY KEY, " +
PERSON_TABLE_COLUMN_NAME + " TEXT, " + PERSON_TABLE_COLUMN_PIN + " TEXT )";
Log.d(TAG, "onCreate SQL: " + buildSQL);
sqLiteDatabase.execSQL(buildSQL);
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
// Database schema upgrade code goes here
String buildSQL = "DROP TABLE IF EXISTS " + TABLE_NAME;
Log.d(TAG, "onUpgrade SQL: " + buildSQL);
sqLiteDatabase.execSQL(buildSQL); // drop previous table
onCreate(sqLiteDatabase); // create the table from the beginning
}
}
}
Use the avarage (avg) aggregate function:
String query = "SELECT AVG("+PERSON_TABLE_COLUMN_PIN +") FROM "+TABLE_NAME;
and then use SQLiteDatabase.rawQuery(String sql, String[] selectionArgs) for executing the query. Something like:
database.rawQuery(query, null);
Here you can find a sample fiddle.
While, for deleting a row, you can use SQLiteDatabase.delete(String table, String whereClause, String[] whereArgs). For example:
String where = PERSON_TABLE_COLUMN_ID+"=?";
String[] whereArgs = new String[]{String.valueOf(59)};
database.delete(TABLE_NAME, where, whereArgs);
the above code delete the row with id 59.