SQLite error for Android: "Column is not unique" - java

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.

Related

Column Constraint error using SQLITE on android

I'm trying to set up a database and name the columns respectively, but I'm getting an error on line 16 with the PRIMARY KEY saying "')' or coma expected got '_title'
public class MyDBHandler extends SQLiteOpenHelper{
private static final int DATABASE_VERSION=1;
private static final String DATABASE_NAME="movies.db";
public static final String TABLE_PRODUCTS="_movies";
public static final String COLUMN_ID="_id";
public static final String COLUMN_TITLE="_title";
public static final String COLUMN_DATERELEASED="_dateReleased";
public static final String COLUMN_FILENAME="_fileName";
public MyDBHandler(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
#Override
public void onCreate(SQLiteDatabase db) {
//INFORMATION ABOUT EACH COLUMN FOR THE TABLE
String query="CREATE TABLE "+TABLE_PRODUCTS+"("+
COLUMN_ID+" INTEGER PRIMARY KEY AUTOINCREMENT "+
COLUMN_TITLE+" TEXT "+
COLUMN_DATERELEASED+"TEXT "+
COLUMN_FILENAME+" TEXT "
+" ); ";
db.execSQL(query);
}
Your query is wrong you forgot to set comma .
Your query is like this
#Override
public void onCreate(SQLiteDatabase db) {
//INFORMATION ABOUT EACH COLUMN FOR THE TABLE
String query="CREATE TABLE "+TABLE_PRODUCTS+"("+
COLUMN_ID+" INTEGER PRIMARY KEY AUTOINCREMENT, "+
COLUMN_TITLE+" TEXT, "+
COLUMN_DATERELEASED+"TEXT, "+
COLUMN_FILENAME+" TEXT "
+" ); ";
db.execSQL(query);
}
You forgot to add comma after each column. Your Query String should be
String query="CREATE TABLE "+TABLE_PRODUCTS+"("+
COLUMN_ID+" INTEGER PRIMARY KEY AUTOINCREMENT, "+
COLUMN_TITLE+" TEXT, "+
COLUMN_DATERELEASED+"TEXT, "+
COLUMN_FILENAME+" TEXT "
+" )";

Error when creating a SQLite DB on Android (Code 1)

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.)

Null Pointer Exception at com.examples.AddAppointment.addEvent(AddAppointment.java:125)

i am getting this error null pointer exception.
Little background
I have a main class, add appointment class and appointmentdata class.
appointmentData class has a method which creates database (SQLite) if not existing. AddAppointment Class gets values from a view with couple editText and user inserts some values and this data should be passed to method addEvent in the same class where the values are inserted to database, earlier created in appointmentData class. however the appointment Data class is never called hence the database is never created and as a result i get null pointer exception (values can not be inserted into db).
Now my questions is. How do i call the class appointmentData in main class so the method onCreate is called and database is created.
Code below
AppointmetData class
public class AppointmentsData extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "appointments.dba";
private static final int DATABASE_VERSION = 1;
private String TIME;
private String DESCRIPTION;
private String DETAILS;
private String DATE;
//create helper object for events database
public AppointmentsData(Context ctx){
super(ctx, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_NAME + " ("
+ _ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ TIME + " TEXT NOT NULL,"
+ DATE + " TEXT NOT NULL"
+ DESCRIPTION + " TEXT NOT NULL"
+ DETAILS + " TEXT NOT NULL");
}
}
AddAppointment Class
public class AddAppointment extends Activity implements OnClickListener {
private AppointmentsData events;
private EditText appDesctription;
private EditText appDate;
private EditText appTime;
private EditText appDetails;
SQLiteDatabase myDB;
//Connection conn; //A connection (session) with a specific database
ResultSet rs; //A table of data representing a database result set, which is usually generated by executing a statement that queries the database.
PreparedStatement pst; //An ob
String TableName = "appointments";
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.appointment_details);
appDate = (EditText) this.findViewById(R.id.appDate);
appDate.setKeyListener(null);
Bundle extras = getIntent().getExtras();
if(extras !=null) {
String dateSelected = extras.getString("dateselected");
appDate.setText(dateSelected);
View saveAppointment = findViewById(R.id.buttonSave);
saveAppointment.setOnClickListener(this);
//SQLiteDatabase db = dbHelper.getWritableDatabase();
}
}
private String DESCRIPTION;
private String DATE;
private String TIME;
private String DETAILS;
#Override
public void onClick(View v) {
appDesctription = (EditText) this.findViewById(R.id.appDescription);
DESCRIPTION = appDesctription.getText().toString();
appTime = (EditText) this.findViewById(R.id.appTime);
TIME = appTime.getText().toString();
appDetails = (EditText) this.findViewById(R.id.appDetails);
DETAILS = appDetails.getText().toString();
DATE = appDate.getText().toString();
AddAppointment aa = new AddAppointment();
aa.addEvent(DESCRIPTION);
aa.addEvent(DATE);
aa.addEvent(DETAILS);
aa.addEvent(TIME);
Intent j = new Intent(this, CalendarViewActivity.class);
startActivity(j);
}
private void addEvent(String string) {
//insert a new record into Events data source
//would do something similar for delete and update
SQLiteDatabase db = events.getWritableDatabase();
ContentValues values = new ContentValues();
// add key and value
values.put(DESCRIPTION, string);
values.put(DATE, string);
values.put(TIME, string);
values.put(DETAILS, string);
db.insertOrThrow(TABLE_NAME, null, values);
}
private String[] FROM = { _ID, TIME, DESCRIPTION, };
private static String ORDER_BY = _ID + "DESC";
private Cursor getEvents(){
//perform managed query. The activity will handle closing
//and requerying the cursor when needed
SQLiteDatabase db = events.getReadableDatabase();
Cursor cursor = db.query(TABLE_NAME, FROM ,null, null, null, null, ORDER_BY);
startManagingCursor(cursor);
return cursor;
}
enter code here
I think your problem is that you have incorrect DML statement in your onCreate() method in SQLiteOpenHelper subclass.
Here:
"CREATE TABLE " + TABLE_NAME + " ("
+ _ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ TIME + " TEXT NOT NULL,"
+ DATE + " TEXT NOT NULL"
+ DESCRIPTION + " TEXT NOT NULL"
+ DETAILS + " TEXT NOT NULL"
you are missing commas behind date and description column and last right parenthesis at the end of statement. This is reason why your database is never created. Try to fix it and it should works.
So here is corrected statement:
"CREATE TABLE " + TABLE_NAME + " ("
+ _ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ TIME + " TEXT NOT NULL,"
+ DATE + " TEXT NOT NULL,"
+ DESCRIPTION + " TEXT NOT NULL,"
+ DETAILS + " TEXT NOT NULL)"

Only allow unique data entry with Android SQLite?

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

Android Database SQLite Average

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.

Categories