sqlite constraint exception primary key must be unique - java

I have 3 tables
Table 1 : Member - To store every information about the member,
Attribute : MemberUsername(PK), MemberPassword
Table 2 : MsGroup - To store every registered group
Attribute : GroupId(PK), GroupName, GroupDescription
Table 3 : MsGroupDetail - To store list of every username in every group
Attribute : GroupId(PK,FK), MemberUsername(PK,FK)
My Query for Creating that 3 tables :
db.execSQL("CREATE TABLE IF NOT EXISTS " + MS_MEMBER + " ("
+ MEMBER_USERNAME + " TEXT PRIMARY KEY NOT NULL, "
+ MEMBER_PASSWORD + " TEXT NOT NULL, " + MEMBER_EMAIL
+ " TEXT NOT NULL" + ");");
db.execSQL("CREATE TABLE IF NOT EXISTS " + MS_GROUP + " ("
+ GROUP_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ GROUP_NAME + " TEXT NOT NULL, " + GROUP_DESCRIPTION
+ " TEXT NOT NULL);");
db.execSQL("CREATE TABLE IF NOT EXISTS " + MS_GROUP_DETAIL + " ("
+ GROUP_ID + " INTEGER PRIMARY KEY, " + MEMBER_USERNAME
+ " TEXT, FOREIGN KEY (" + MEMBER_USERNAME
+ ") REFERENCES " + MS_MEMBER + "(" + MEMBER_USERNAME
+ "), FOREIGN KEY (" + GROUP_ID + ") REFERENCES "
+ MS_GROUP + "(" + GROUP_ID + "));");
I have successfully make some code to create member, create group, but the problem is I failed to create a query to invite/add a new member to a group (Failed to insert to MsGroupDetail)
This is the syntax for adding GroupMember
public void addGroupMember(String groupId, String username) {
// TODO Auto-generated method stub
ContentValues cv2 = new ContentValues();
cv2.put(GROUP_ID, groupId);
cv2.put(MEMBER_USERNAME, username);
ourDatabase.insert(MS_GROUP_DETAIL, null, cv2);
}
And this is the syntax to see the list of my Groups
public String[] fetchGroupName(String username) {
int i = 0;
String Query = "SELECT " + GROUP_NAME + " From " + MS_GROUP
+ " a INNER JOIN " + MS_GROUP_DETAIL + " b ON a." + GROUP_ID
+ "=b." + GROUP_ID + " WHERE " + MEMBER_USERNAME + "=?";
Cursor c = ourDatabase.rawQuery(Query, new String[] { username });
String groupName[] = new String[c.getCount()];
int iGroupName = c.getColumnIndex(GROUP_NAME);
c.moveToFirst();
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
groupName[i] = c.getString(iGroupName);
i++;
}
c.close();
return groupName;
}
Everytime I invite a new member/adding to MsGroupDetail table, I failed to insert it to MsGroupDetail and the log cat said : "SQLite Constraint Exception, primary key must be unique"
*nb : My MsGroupDetail is once again to list every member within a group,
I have tested the same concept in Sql Server Management Studio 2008 and It worked, aI dont know any better concept than what I've coded above,
Can you guys please tell me is there any solution for this?
Thank you so much..

The problem is your GROUP_ID is not unique. If you have two members in group 1, your table will have two entries --
1, Member 1
1, Member 2
By specifying "PRIMARY KEY" on GROUP_ID you are stating it will be unique. You need different primary key. In android, it is common to use "_id", something like --
db.execSQL("CREATE TABLE IF NOT EXISTS " + MS_GROUP_DETAIL + " ("
+ "_id INTEGER PRIMARY KEY AUTOINCREMENT,"
+ GROUP_ID + " INTEGER, " + MEMBER_USERNAME
+ " TEXT, FOREIGN KEY (" + MEMBER_USERNAME
+ ") REFERENCES " + MS_MEMBER + "(" + MEMBER_USERNAME
+ "), FOREIGN KEY (" + GROUP_ID + ") REFERENCES "
+ MS_GROUP + "(" + GROUP_ID + "));");

Related

SQLite query for ordering a list based on mistakes made

I would like to know how to query a database based on the amount of mistakes made by a waiter.
The two tables I have are
Employee
String employeeTable = "CREATE TABLE " + EMP_TABLE + " ("
+ ID_EMP + " INTEGER PRIMARY KEY, "
+ FIRST_NAME + " TEXT,"
+ LAST_NAME + " TEXT,"
+ PROFIT + " INTEGER);";
MistakeEmployee
String mistakeTable = "CREATE TABLE " + MISTAKE_TABLE + " ("
+ ID_MISTAKE + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ ID_WAITER_MISTAKE + " INTEGER,"
+ ID_ORDER_MISTAKE + " INTEGER,"
+ MISTAKE_TOTAL + " INITGER,"
+ " FOREIGN KEY (" + ID_WAITER_MISTAKE + ") REFERENCES " + EMP_TABLE + "(" + ID_EMP + "), "
+ " FOREIGN KEY (" + ID_ORDER_MISTAKE + ") REFERENCES " + ORDER_TABLE + "(" + ID_ORDER + "));";
I am trying to order the list based on the Employee with the most Mistakes which would be counted in the mistakes table using the ID_WAITER_MISTAKE.
String query = SELECT * , COUNT(Mistake_TABLE.ID_Waiter) as Count
FROM EMP_TABLE
ORDER BY Count DESC
You must join the tables, group by employee and aggregate:
SELECT e.ID_EMP, e.FIRST_NAME, e.LAST_NAME,
COUNT(m.ID_MISTAKE) AS Mistake_Count
FROM employeeTable e LEFT JOIN mistakeTable m
ON m.ID_WAITER_MISTAKE = e.ID_EMP
GROUP BY e.ID_EMP, e.FIRST_NAME, e.LAST_NAME
ORDER BY Mistake_Count DESC, e.ID_EMP
and in Java code you should construct the sql string like this:
String query =
"SELECT e." + ID_EMP + ", e." + FIRST_NAME + ", e." + LAST_NAME + ", " +
"COUNT(m." + ID_MISTAKE + ") AS Mistake_Count " +
"FROM " + EMP_TABLE + "AS e LEFT JOIN " + MISTAKE_TABLE + " AS m " +
"ON m." + m.ID_WAITER_MISTAKE + " = e." + ID_EMP + " " +
"GROUP BY e." + ID_EMP + ", e." + FIRST_NAME + ", e." + LAST_NAME + " " +
"ORDER BY Mistake_Count DESC, e." + ID_EMP ;
I hope there are no typos.

SQLiteException no such table, am I missing something?

I have researched other instances of this error all morning but nothing i've tried so far has worked. It could be something obvious as I am quite new to this.
I am trying to return the results of the GET_ALL_INGREDIENTS query. Which I will then put into a 2d array, but you don't need to worry about that. My TABLE_RECIPES table works fine.
SQLiteException: no such table: TABLE_INGREDIENTS (code 1): , while compiling: SELECT INGR...etc....
Which occurs on the last line of this bit of code:
public String[][] getRecipeIngredients(int id) {
String GET_ALL_INGREDIENTS = "SELECT INGREDIENT_NAME, INGREDIENT_QUANTITY, INGREDIENT_UNIT " +
"FROM TABLE_INGREDIENTS " +
"INNER JOIN TABLE_RECIPE_INGREDIENTS ON TABLE_RECIPE_INGREDIENTS.INGREDIENT_ID=TABLE_INGREDIENTS.INGREDIENT_ID " +
"WHERE RECIPE_INGREDIENTS.RECIPE_ID=" + id;
db = new MyDBHandler(mContext);
SQLiteDatabase db = this.getReadableDatabase();
Cursor c = db.rawQuery(GET_ALL_INGREDIENTS, null);
Table Creation:
final String CREATE_TABLE_RECIPES = "CREATE TABLE IF NOT EXISTS " +
TABLE_RECIPES + "(" +
RECIPE_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
RECIPE_NAME + " TEXT, " +
RECIPE_INSTRUCTIONS + " TEXT " +
")";
final String CREATE_TABLE_INGREDIENTS = "CREATE TABLE IF NOT EXISTS " +
TABLE_INGREDIENTS + "(" +
INGREDIENT_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
INGREDIENT_NAME + " TEXT NOT NULL UNIQUE " +
")";
final String CREATE_TABLE_RECIPE_INGREDIENTS = "CREATE TABLE IF NOT EXISTS " +
TABLE_RECIPE_INGREDIENTS + "(" +
RECIPE_ID + " INTEGER NOT NULL, " +
INGREDIENT_ID + " INTEGER NOT NULL, " +
INGREDIENT_QUANTITY + " REAL, " +
INGREDIENT_UNIT + " TEXT, " +
"PRIMARY KEY (" + RECIPE_ID + "," + INGREDIENT_ID + "), " +
"FOREIGN KEY (" + RECIPE_ID + ") REFERENCES " + TABLE_RECIPES + "(" + RECIPE_ID + "), " +
"FOREIGN KEY (" + INGREDIENT_ID + ") REFERENCES " + TABLE_INGREDIENTS + "(" + INGREDIENT_ID + ")" +
")";
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE_RECIPES);
db.execSQL(CREATE_TABLE_INGREDIENTS);
db.execSQL(CREATE_TABLE_RECIPE_INGREDIENTS);
}
Thank you for reading and I really appreciate any help i can get with this.
TABLE_INGREDIENTS is a variable. It's value is likely not "TABLE_INGREDIENTS" that is a string literal. So you might want to change
"FROM TABLE_INGREDIENTS " +
to
"FROM " + TABLE_INGREDIENTS +
(You have a number of other similar issues in your SQL too.)

Creating 2 tables - ORA-00904: : invalid identifier

I am trying to create 2 tables: Person and Friend.
In the Friends table, I have a composite primary foreign key that references personId from the Person Table.
Please note i'm trying to do this in Java (Eclipse IDE).
I keep getting this error when I'm trying to create the Friends table for some reason:
ORA-00904: : invalid identifier
String createPersonalInformationTable =
"CREATE TABLE Persons("
+ "personId INT NOT NULL, "
+ "email_userName VARCHAR2(50) NOT NULL, "
+ "password VARCHAR2(50) NOT NULL, "
+ "firstName VARCHAR2(50) NOT NULL, "
+ "midlleName VARCHAR2(50), "
+ "lastName VARCHAR2(50) NOT NULL, "
+ "country VARCHAR2(50) NOT NULL, "
+ "city VARCHAR2(50) NOT NULL, "
+ "PRIMARY KEY (personId), "
+ "UNIQUE (email_userName)"
+ ")";
String createFriendsTable =
"CREATE TABLE Friends("
+ "personId INT NOT NULL, "
+ "friendId INT NOT NULL, "
+ "status VARCHAR2(50) NOT NULL, "
+ "PRIMARY KEY (personId, friendId), "
+ "FOREIGN KEY (personId) REFERENCES Persons(personId), "
+ "FOREIGN KEY (friendId) REFERENCES Persons(personId), "
+ ")";
String createFriendsTable =
"CREATE TABLE Friends("
+ "personId INT NOT NULL, "
+ "friendId INT NOT NULL, "
+ "status VARCHAR2(50) NOT NULL, "
+ "PRIMARY KEY (personId, friendId), "
+ "FOREIGN KEY (personId) REFERENCES Persons(personId), "
+ "FOREIGN KEY (friendId) REFERENCES Persons(personId), "
^
+ ")";
Extra trailing comma

MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails

I have probed numerous questions and documentation on this error and cannot seem to find where I am going wrong. The error is on this line:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
Cannot add or update a child row: a foreign key constraint fails (`flutweets`.`refs`,
CONSTRAINT `refs_ibfk_1` FOREIGN KEY (`id`) REFERENCES `tweets` (`id`))
The database is MySQL, and I am using Workbench to inspect it; I also know that all the database engines are InnoDB and the Row Formats are Compact. I have three tables: tweets, hashtags, and references.
Here is where I create the tables:
tweets Table
Statement stmt = null;
try {
stmt = connection.createStatement();
stmt.executeUpdate("CREATE TABLE " + TWEETS_TABLE + "("
+ TWEETS_ID + " BIGINT NOT NULL AUTO_INCREMENT,"
+ TWEETS_TIME + " VARCHAR(255),"
+ TWEETS_USER + " VARCHAR(255),"
+ TWEETS_TEXT + " VARCHAR(255) NOT NULL,"
+ TWEETS_LOCATION + " VARCHAR(255),"
+ TWEETS_CITY + " VARCHAR(255),"
+ TWEETS_PROVINCE + " VARCHAR(255),"
+ TWEETS_COUNTRY + " VARCHAR(255),"
+ TWEETS_TIME_ZONE + " VARCHAR(255),"
+ TWEETS_LATITUDE + " DECIMAL(20,16),"
+ TWEETS_LONGITUDE + " DECIMAL(20,16),"
+ "PRIMARY KEY (" + TWEETS_ID + ")"
+ ")");
. . .
hashtags Table
Statement stmt = null;
try {
stmt = connection.createStatement();
stmt.executeUpdate("CREATE TABLE " + HASHTAG_TABLE + "("
+ HASHTAG_ID + " BIGINT NOT NULL AUTO_INCREMENT,"
+ HASHTAG_TEXT + " VARCHAR(255),"
+ TWEETS_ID + " BIGINT NOT NULL,"
+ "PRIMARY KEY (" + HASHTAG_ID + "),"
+ "FOREIGN KEY (" + TWEETS_ID + ")"
+ "REFERENCES " + TWEETS_TABLE
+ "(" + TWEETS_ID + ")"
+ ")");
. . .
references Table
Statement stmt = null;
try {
stmt = connection.createStatement();
stmt.executeUpdate("CREATE TABLE " + REF_TABLE + "("
+ REF_ID + " BIGINT NOT NULL AUTO_INCREMENT,"
+ REF_TEXT + " VARCHAR(255),"
+ TWEETS_ID + " BIGINT NOT NULL,"
+ "PRIMARY KEY (" + REF_ID + "),"
+ "FOREIGN KEY (" + TWEETS_ID + ")"
+ "REFERENCES " + TWEETS_TABLE
+ "(" + TWEETS_ID + ")"
+ ")");
Here are the statements I use to insert and the methods to insert them (I am using prepared statements):
/* INITIALIZE PREPARED STATEMENTS */
// Tweets
private static final String TWEETS_INSERT = "INSERT INTO " + TWEETS_TABLE
+ " (" + TWEETS_TIME + ", " + TWEETS_USER + ", " + TWEETS_TEXT + ", " + TWEETS_LOCATION + ", " + TWEETS_CITY + ", " + TWEETS_PROVINCE + ", "
+ TWEETS_COUNTRY + ", " + TWEETS_TIME_ZONE + ", " + TWEETS_LATITUDE + ", " + TWEETS_LONGITUDE + ")"
+ " VALUES(?,?,?,?,?,?,?,?,?,?)";
private PreparedStatement tweetsStatement;
// Hashtags
private static final String HASHTAGS_INSERT = "INSERT INTO " + HASHTAG_TABLE
+ " (" + HASHTAG_TEXT + ", " + TWEETS_ID + ")" + " VALUES(?,?)";
private PreparedStatement hashStatement;
// References
private static final String REF_INSERT = "INSERT INTO " + REF_TABLE
+ " (" + REF_TEXT + ", " + TWEETS_ID + ")" + " VALUES(?,?)";
private PreparedStatement refStatement;
public void insertHashtag(FluTweet tweet, int hashIndex, Integer tweetID) {
// Pull all of the Hashtag's relevant elements.
String hashText = tweet.getHashtag(hashIndex);
try {
hashStatement.setString(1, hashText);
hashStatement.setString(2, tweetID.toString());
//INSERT HASHTAG INTO TABLE
hashStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
public void insertReference(FluTweet tweet, int referenceIndex, Integer tweetID) {
// Pull all of the Reference's relevant elements.
String refText = tweet.getReference(referenceIndex);
try {
refStatement.setString(1, refText);
refStatement.setString(2, tweetID.toString());
//INSERT REFERENCE INTO TABLE
refStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
I have no idea why this is not working, any help would be much appreciated. Like I said, I have probed numerous other posts and cannot find relevant help.
Background
I found out the answer to my own question. It was never a problem with any of the actual database handling. It turns out, when I was passing the id to be used as the foreign id in hashtags and references, I was getting my id from a counter in the main class; where every new tweet had a number that went with each hashtag and reference for that tweet that would later be used as a foreign key. That foreign key would reference the primary key in the tweets table, which auto increments.
Here was the problem:
It turns out that MySQL is NOT zero-indexed when you auto-increment; where the first value is zero, then one, then two, etc. Instead, it starts at one. So when I tried to reference the primary key with the foreign key, the counter that started at zero for every tweet that I assigned (the foreign key) was being incorrectly matched to the auto incrementing tweet id in the tweets table (primary key).
Therefore, I was always off by one.
I hope this helps anyone that may have a similar issue.
if we didn't set valid child class object primary key value then we can see the MySQLIntegrityConstraintViolationException.if we ignore the primary key value of child class object then based on the configurations set in hibernate pojo/hbm.xml files first level cache(session) will flush it into data base.

sqlite table creation

Im unsure of my problem. I am getting no such table when queriyng the second table.. these are both within the onCreate method
db.execSQL("CREATE TABLE " + DATABASE_TABLE + " (" + KEY_CBID
+ " INTEGER PRIMARY KEY AUTOINCREMENT, " + KEY_NAME
+ " TEXT NOT NULL, " + KEY_RACE + " TEXT NOT NULL,"
+ KEY_CLASS + " TEXT NOT NULL," + KEY_DEITY
+ " TEXT NOT NULL," + KEY_GENDER + " TEXT NOT NULL,"
+ KEY_HEIGHT + " TEXT NOT NULL," + KEY_WEIGHT
+ " TEXT NOT NULL);");
db.execSQL("CREATE TABLE " + DATABASE_TABLE2 + " (" + KEY_CSID
+ " INTEGER PRIMARY KEY AUTOINCREMENT, " + KEY_SKILL
+ " TEXT NOT NULL, " + KEY_CBID + " INTEGER PRIMARY KEY FOREIGN KEY);"
);
Edit: showing cvs
String skill = "blah test";
Cursor c = ourDatabase.rawQuery("SELECT " + KEY_CBID + " FROM " + DATABASE_TABLE + " order by " + KEY_CBID + " DESC limit 1", null);
if (c != null)
{
c.moveToFirst();
cbid = c.getInt(0);
}
ContentValues cv = new ContentValues();
cv.put(KEY_SKILL, skill);
cv.put(KEY_CBID, cbid);
return ourDatabase.insert(DATABASE_TABLE2, null, cv);
My select statements is:
Cursor c = ourDatabase.rawQuery("SELECT " + KEY_SKILL + ", " + KEY_NAME + ", " + KEY_CBID + " FROM " + DATABASE_TABLE + ", " + DATABASE_TABLE2 + " WHERE " + DATABASE_TABLE +"."+KEY_CBID+" = " +DATABASE_TABLE2+"."+KEY_CBID+" && " +DATABASE_TABLE+"."+KEY_NAME+" = '"+item+"'", null);
I don't believe that your second table is being created, here is how to declare a table with a foreign key:
CREATE TABLE artist(
artistid INTEGER PRIMARY KEY,
artistname TEXT
);
CREATE TABLE track(
trackid INTEGER,
trackname TEXT,
trackartist INTEGER,
FOREIGN KEY(trackartist) REFERENCES artist(artistid)
);
I took these from SQLite.org.
Also foreign keys are disabled by default in SQLite, for Android use:
db.execSQL("PRAGMA FOREIGN_KEYS=ON;");
before inserting data, if you haven't already;
check you log cat to see if there is an error while creating the second table.
If there is an error from sqllite, it will be logged in logcat
When a new table is added to DB, make sure DB is upgraded
IF from your code if you are calling db.open , if the database is already created it will be open. So in this case the code to create new table will not be hit. So you have to make sure that you upgrade the database where you can delete all your existing tables and create again
#Override
public void onCreate(SQLiteDatabase db) {
createAllTables(db);
Log.v(DBTAG, "DATABASE CREATED");
// Toast.makeText(mCtx, "created", Toast.LENGTH_SHORT).show();
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(DBTAG, "Upgrading database from version " + oldVersion
+ " to " + newVersion + ", which will destroy all old data");
dropExistingTables(db);
onCreate(db);
}
private void dropExistingTables(SQLiteDatabase db) {
for (int i = 0; i < Utils.getDropTableQueries().size(); i++) {
db.execSQL(Utils.getDropTableQueries().get(i));
}
}
Thus to conclude make sure you are creating the table, and that no error while creating.

Categories