FTS3 | rowid problems | delete dont work - java

I recently updated my database to FTS3 due to that I implented search functionality.
My FTS3 table:
db.execSQL("CREATE VIRTUAL TABLE " + TABLE_FTS + " USING fts3(" + COL_ID + ", " + COL_KEY_NAME + ", "
+ COL_KEY_WEBURL + " , " + COL_KEY_MAINURL + ", " + COL_KEY_CODEC + " " + ");");
I always deletet entrys from my listview with the ContextMenu. I used a method like this:
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
delete(info.id);
updateList();
public void delete(long id) {
int numDeleted = database.delete("stations" , "_ID = ?", new String[] { Long.toString(id) } );
Log.d(TAG, "delete(): id=" + id + " -> " + numDeleted);
}
public void updateList() {
data.requery();
dataSource.notifyDataSetChanged();
}
The method, info.id don't get me the position, so I'am changed it to info.position. Position is right, but delet dont work. Ok, than I tried a simple delete instead of via Android Method.
database.execSQL("DELETE FROM " + DatabaseHelper.TABLE_FTS + " WHERE " + DatabaseHelper.COL_ID + "='" + id + "'");
Don't work, too. It seems that the column, COL_KEY_ID = BaseColumns._ID with an autoincrementing number don't exists in FTS3 anymore? I figured out, that I could use rowid but its not working as intended. If I delete my first entry, the entrys below get weird deleted.
How I can get this back working like before?
Edit: Found now fix ..

Found fix. Don't delete by ID, delete now by name.

I assume the problem comes from
_ID = ?
_ID is an integer yet ? is replaced by a String. Same for your second not working approach.

Related

Database does not store data. I get the "SQLiteLog: (1) near "Name": syntax error" from Android Studio log

I get from "SQLiteLog: (1) near "Name": syntax error" after the addPatient() method is called and the data given by addPatient() method is not stored in the database.
At first, I suspect that something might be wrong with my "CREATE TABLE" query but I have tried everything and I couldn't figure out what was wrong.
#Override
public void onCreate(SQLiteDatabase db)
{
//===============Create a table for Patient
String query = "CREATE TABLE TABLE_PATIENT (COLUMN_ID INTEGER PRIMARY KEY AUTOINCREMENT, " +
"COLUMN_USERNAME TEXT, " +
"COLUMN_PASSWORD TEXT, " +
"COLUMN_FIRSTNAME TEXT, " +
"COLUMN_LASTNAME TEXT, " +
"COLUMN_AGE TEXT, " +
"COLUMN_GENDER TEXT, " +
"COLUMN_PHONE TEXT, " +
"COLUMN_ADDRESS TEXT);";
db.execSQL(query);
}//End of onCreate()
//Add a new Patient Row to the database
public void addPatient(Patient patient)
{
Log.i(TAG, "addPatient("+patient.getUserName()+")");
ContentValues values = new ContentValues();
values.put(COLUMN_ID, patient.getU_Id());
values.put(COLUMN_USERNAME, patient.getUserName());
values.put(COLUMN_PASSWORD, patient.getPassword());
values.put(COLUMN_FIRSTNAME, patient.getFirstName());
values.put(COLUMN_LASTNAME,patient.getLastName());
values.put(COLUMN_AGE, patient.getAge());
values.put(COLUMN_GENDER,patient.getGender());
values.put(COLUMN_PHONE,patient.getPhoneNumber());
values.put(COLUMN_ADDRESS, patient.getAddress());
SQLiteDatabase db = getWritableDatabase();
try
{
db.insert(TABLE_PATIENT, null, values);
db.close();
}catch (Exception e)
{
Log.i(TAG, e.getMessage());
}
}//End of addPatient()
I guess you have defined these variables:
String COLUMN_ID = "id";
String COLUMN_USERNAME = "username";
....................................
or something like that.
If you have spaces in the names of the columns you must use square brackets or backticks around them, like:
String COLUMN_USERNAME = "[user name]";
In your CREATE TABLE statement you define the column names as:
"COLUMN_ID", "COLUMN_USERNAME", ....
because you use the variable names and not their values.
But in addPatient() method you are putting values to the ContentValues object by using their actual names.
To solve your problem, 1st uninstall the app from the device you are testing it, so the database is deleted.
Then change the CREATE TABLE statement like this:
String query = "CREATE TABLE " + TABLE_PATIENT +" (" +
COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COLUMN_USERNAME + " TEXT, " +
COLUMN_PASSWORD + " TEXT, " +
COLUMN_FIRSTNAME + " TEXT, " +
COLUMN_LASTNAME + " TEXT, " +
COLUMN_AGE + " TEXT, " +
COLUMN_GENDER + " TEXT, " +
COLUMN_PHONE + " TEXT, " +
COLUMN_ADDRESS + " TEXT)";
and rerun to recreate the database with the correct column names.

java postgresql ERROR: cached plan must not change result type

I'm having a weird problem on my application, I'm receiving this error on one of my query's:
SEVERE: java.sql.SQLException: ERROR: cached plan must not change result type.
I only get this error in my production environment.
I can't find anything wrong or different, except that in the developer environment I'm using a maven jetty:run to start the app (Maven 3.3.9), and in production I have an Apache Tomcat v.8.0.30. The java version on my development environment is a little more updated 1.8.0_73 vs 1.8.0_71-b15 in production, that's all.
For a moment I believed it was my database, but then the problem should show up in both production and developer, but that's not happening only production is affected.
My database is on a PostgreSQL 9.4.9.
Thank you in advance.
******** EDIT *******
I did checkout this link: Postgres 8.3: "ERROR: cached plan must not change result type" but I have no scripts altering my tables or its columns.
***** EDIT 2 *****
I add the code:
static public ArrayList<OKCalendarEvent> listAllEventsByCalendarAndStatusBetween(String idCalendar,
Timestamp from,
Timestamp to,
OKCalendarEventStatus status ,
WDataSource ds) throws OklexDataException {
ArrayList<OKCalendarEvent> events = new ArrayList<>();
String sql = "SELECT " +
" e.idreg ," +
" e.calendar_id ," +
" e.event_processid, " +
" e.event_fieldid, " +
" e.event_code," +
" e.event_name ," +
" e.event_description ," +
" e.user_id ," +
" e.event_start ," +
" e.event_end ," +
" e.event_duration ," +
" e.event_status ," +
" e.event_type ," +
" e.event_buffer ," +
" e.tfc , "+
" e.id_event_origin ," + //20160729
" e.frequencyType ," + //20160729
" e.frequencyEnd ," + //20160729
" e.invitees, " + //20160729
" (u.firstname ||' ' || u.lastname) as fullUserName " + //20160802
"FROM ok_calendar_event e " +
"LEFT JOIN ok_user u " +
"ON e.user_id=u.userid " +
"WHERE e.calendar_id = ? AND e.event_status = ? AND e.event_start BETWEEN ? AND ?;";
try {
List<Object[]> rs = WData.doQuery(ds, sql, idCalendar, status.getEventStatus(), from, to);
for (Object[] obj : rs) {
OKCalendarEvent event = new OKCalendarEvent();
event.setIdreg(NumberUtils.parseToInt(obj[0].toString()));
event.setCalendarId(obj[1].toString());
event.setIdProcess(NumberUtils.parseToLong(obj[2].toString()));
event.setFieldId(obj[3].toString());
event.setCode(obj[4].toString());
event.setName(obj[5].toString());
event.setDescription(obj[6].toString());
event.setUserId(obj[7].toString());
event.setStart(CalendarUtils.stringToTimeStamp(obj[8].toString(), Constants.dateTimeFormat));
event.setEnd(CalendarUtils.stringToTimeStamp(obj[9].toString(), Constants.dateTimeFormat));
event.setDuration(NumberUtils.parseToInt(obj[10].toString(), 0));
event.setStatus(NumberUtils.parseToInt(obj[11].toString(), 0));
event.setType(NumberUtils.parseToInt(obj[12].toString(), 0));
event.setBuffer(obj[13].toString());
event.setTfc(CalendarUtils.stringToTimeStamp(obj[14].toString(), Constants.dateTimeFormat));
//20160729
event.setId_event_origin( NumberUtils.parseToInt(obj[15].toString()) );
event.setFrequency_type( NumberUtils.parseToInt(obj[16].toString()) );
if(obj[17]!=null) {
event.setFrequency_end(CalendarUtils.stringToTimeStamp(obj[17].toString(), Constants.dateTimeFormat));
}
event.setInvitees(obj[18].toString());
event.setUserFullName(obj[19].toString());
events.add(event);
}
} catch (Exception e) {
// process = new ArrayList<Process>();
log.error(" | listAllEventsByCalendarAndStatusBetween | failed, cause: "+ e.toString());
throw new OklexDataException("There was a problem retrieving the OKCalendar list from the database.", e);
}
return events;
}

how to pass positional parameters to createnativequery jpa java

I have the following SQL query in my j2ee web app that I am unable to get to work, as-is. The named parameters sourceSystem and sourceClientId do not appear to get passed to the query, and therefore it does not return any records. I added a watch to the Query object querySingleView and it maintained a value of null as the debugger ran through the code. I also inserted a System.out.println statement just under the method declaration and confirmed that the correct values sourceSystem and sourceClientId are being passed to the method signature. I am using NetBeans 8.0, JPA 2.1, running on a JBoss EAP 6.21 server. I have multiple Entities mapped to several tables in an Oracle database.
Here is the query (I should note that the items in the query follow a schema.table.column format - not sure if that is part of the problem, but it does work in one test, see my comment and sample below the main query below):
public List<String> searchSingleView (String sourceSystem, String sourceClientId) {
//Change the underscore character in the source system value to a dash, and make it uppercase. This is what single view accepts
if (!sourceSystem.equals("")) {
sourceSystemSingleView = sourceSystem.replace('_', '-').toUpperCase();
}
String sqlSingleViewQuery = "SELECT DISTINCT " +
"MDMCUST_ORS.C_BO_CONTRACT.LAST_ROWID_SYSTEM AS POLICY_SYSTEM, " +
"MDMCUST_ORS.C_BO_CONTRACT.SRC_POLICY_ID AS POLICY_ID, " +
"MDMCUST_ORS.C_BO_CONTRACT.ISSUE_DT, " +
"MDMCUST_ORS.C_BO_PARTY_XREF.SRC_CLIENT_ID AS SRC_CLIENT_ID, " +
"MDMCUST_ORS.C_BO_PARTY_XREF.PERS_FULL_NAME_TXT, " +
"MDMCUST_ORS.C_BO_PARTY_XREF.ORG_LEGAL_NAME_TXT, " +
"MDMCUST_ORS.C_BO_PARTY_XREF.ORG_LEGAL_SFX_TXT, " +
"MDMCUST_ORS.C_BO_PARTY_XREF.ORG_NAME_TXT, " +
"MDMCUST_ORS.C_BO_PARTY_XREF.SIN_BIN_TEXT, " +
"MDMCUST_ORS.C_BO_PARTY_XREF.PERS_BIRTH_DT, " +
"MDMCUST_ORS.C_LU_CODES.CODE_DESCR_EN AS ADDRESS_PURPOSE_CD, " +
"MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR.COMPLETE_ADDRESS_TXT, " +
"MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR.CITY_NAME, " +
"MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR.COUNTRY_NAME, " +
"MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR.POSTAL_CD, " +
"MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR.STATE_PROVINCE_NAME " +
"FROM MDMCUST_ORS.C_BO_PARTY_XREF " +
"LEFT JOIN MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR ON MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR.PARTY_ROWID = MDMCUST_ORS.C_BO_PARTY_XREF.ROWID_OBJECT " +
"LEFT JOIN MDMCUST_ORS.C_LU_CODES ON MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR.POSTAL_ADDR_PURPOSE_CD = MDMCUST_ORS.C_LU_CODES.CODE " +
"LEFT JOIN MDMCUST_ORS.C_BO_PARTY_REL ON MDMCUST_ORS.C_BO_PARTY_XREF.ROWID_OBJECT = MDMCUST_ORS.C_BO_PARTY_REL.FROM_PARTY_ROWID " +
"LEFT JOIN MDMCUST_ORS.C_BO_CONTRACT ON MDMCUST_ORS.C_BO_PARTY_REL.CONTRACT_ROWID = MDMCUST_ORS.C_BO_CONTRACT.ROWID_OBJECT " +
"WHERE MDMCUST_ORS.C_BO_CONTRACT.LAST_ROWID_SYSTEM = :sourceSystemSingleView " +
"AND MDMCUST_ORS.C_BO_PARTY_XREF.SRC_CLIENT_ID = :sourceClientId " +
"AND MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR.POSTAL_ADDR_PURPOSE_CD = '56|07' " +
"AND MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR.LAST_ROWID_SYSTEM = MDMCUST_ORS.C_BO_CONTRACT.LAST_ROWID_SYSTEM " +
"ORDER BY MDMCUST_ORS.C_BO_CONTRACT.LAST_ROWID_SYSTEM";
querySingleView = emSingleView.createQuery(sqlSingleViewQuery);
querySingleView.setParameter("sourceSystemSingleView", sourceSystemSingleView);
querySingleView.setParameter("sourceClientId", sourceClientId);
querySingleViewResult = (List<String>) querySingleView.getResultList();
return querySingleViewResult;
}
}
However, if I put literal values in the SQL query in place of the positional parameters it works fine (without using the setParameter method).
WHERE MDMCUST_ORS.C_BO_CONTRACT.LAST_ROWID_SYSTEM = 'ADMIN' " +
"AND MDMCUST_ORS.C_BO_PARTY_XREF.SRC_CLIENT_ID = '0000001234' " +
I have looked online but haven't as yet found anything that seems to address this specific question. Any help would be greatly appreciated. Thank you!

Sqlite insert and update values of other columns

I have two tables; a 'parent' and a 'child' table. (not SQLite defitinions, just something i call them)
Everytime a child-object is created, it is assigned the value 0 in one of its columns.
When a new parent-object is created, every unassigned child-object, has to update the value mentioned before, to the parent-object's ID. My code looks like this:
public long createWorkout(String workoutName){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_NAME, workoutName);
//Creates a new parent-object (a workout - the childs are exercises)
//the generated ID is returned as a long (workout_pk_id)
long workout_pk_id = db.insert(TABLE_WORKOUT, null, values);
//Selects all objects in the child-table with KEY_WORKOUT_ID = 0 (the column mentioned before)
String selectQuery = "SELECT * FROM " + TABLE_EXERCISE + " WHERE " + KEY_WORKOUT_ID + " == " + 0;
Cursor cursor = db.rawQuery(selectQuery, null);
//Takes each found object with value 0, and updates the value to the returned parent-ID from before.
if (cursor.moveToFirst()) {
do {
String k = "UPDATE " + TABLE_EXERCISE + " SET " + KEY_WORKOUT_ID + " == " + workout_pk_id;
db.execSQL(k);
} while (cursor.moveToNext());
}
return workout_pk_id;
}
But for some reason this doesn't work. The ID the childs/exercises remains 0. Can you help me?
I don't know if the error is somewhere in the setup of my tables, in that case i could provide some more information.
Thanks in advance. /Jeppe
EDIT: This is used in android, and I have debugged and verified that the workout_pk_id is returned, 45 objects are found in the selectQuery and yet it doesn't work. I also tried ContentValues to update the values, didn't work.
Edited the " == " to " = ", but the value is still not updated.
This is from eclipse - I've created a workout called "test", with the ID 160.
The exercise "test1" has the ID 430 (unique) but the workout_id is still 0.
It's been awhile since I did any Android stuff but I believe the "==" operator is incorrect:
String k = "UPDATE " + TABLE_EXERCISE + " SET " + KEY_WORKOUT_ID + " == " + workout_pk_id;
The operator you're using is a comparative operator, "=" is the assignment operator.
I also believe there is a better way to do what you are trying to do, currently refreshing my memory on Android so I'll get back to you. In the meantime tell me if replacing the operator works
Yeah so another way you can do this is by using subqueries. So it would look something like:
UPDATE TABLE_EXCERCISE SET KEY_WORKOUT_ID = WORKOUT_PK_ID WHERE KEY_WORKOUT_ID =
(
*subquery here to select parent object ids*
)
Here's a link to help:
http://www.tutorialspoint.com/sqlite/sqlite_sub_queries.htm
Let me know how this works for you.
I think you have to look to your update query.
It has to be:
String k = "UPDATE " + TABLE_EXERCISE + " SET " + KEY_WORKOUT_ID + " = " + workout_pk_id;
Look at the "=" between KEY_WORKOUT_ID and workout_pk_id.

Android SQLite Couldn't Found Declared Column

Okay, here's the situation: I've created a class extending Android's SQLOpenHelper class. I've also implemented the required methods, onCreate and onUpgrade, to initialize tables and to drop the current tables and then re-create new ones respectively.
The tables were successfully created but when I tried to call a method to insert a new record to the database LogCat gave me this instead:
06-17 21:31:19.907: I/SqliteDatabaseCpp(561): sqlite returned: error code = 1, msg = table calendarEvents has no column named colour, db=/data/data/stub.binusitdirectorate.calendar/databases/calendarSQLite
I've done some search regarding this problem. Most of the answers suggested to re-install the app and repeat the process. Done, but still no success.
Here's my SQLiteOpenHelper onCreate method:
public void onCreate(SQLiteDatabase db) {
String CREATE_EVENTS_TABLE = "CREATE TABLE " + EVENTS_TABLE + "("
+ KEY_EVENTS_TYPE_ID + " TEXT PRIMARY KEY,"
+ KEY_EVENTS_TYPE_NAME + " TEXT," + KEY_EVENTS_NAME + " TEXT,"
+ KEY_EVENTS_COLOR + "TEXT," + KEY_EVENTS_START_DATE + "DATE,"
+ KEY_EVENTS_END_DATE + "TEXT" + ")"
db.execSQL(CREATE_EVENTS_TABLE);
}
And here's my method for inserting new records:
public void addEventsList(ArrayList<CalendarEventData> lstCalendarEvents) {
SQLiteDatabase db = this.getWritableDatabase();
if (lstCalendarEvents != null && db != null) {
for (int i = 0; i < lstCalendarEvents.size(); i++) {
ContentValues values = new ContentValues();
values.put(KEY_EVENTS_TYPE_ID, lstCalendarEvents.get(i)
.getEventTypeId());
values.put(KEY_EVENTS_TYPE_NAME, lstCalendarEvents.get(i)
.getEventTypeName());
values.put(KEY_EVENTS_NAME, lstCalendarEvents.get(i)
.getEventName());
values.put(KEY_EVENTS_COLOR, lstCalendarEvents.get(i)
.getColour());
values.put(KEY_EVENTS_START_DATE, DateUtils
.getFormattedDateString(lstCalendarEvents.get(i)
.getStartDateTime(), dateFormat));
values.put(KEY_EVENTS_END_DATE, DateUtils
.getFormattedDateString(lstCalendarEvents.get(i)
.getEndDateTime(), dateFormat));
db.insert(EVENTS_TABLE, null, values);
}
db.close();
}
}
I'm fairly new to Android and was using this tutorial as a guide.
Thanks in advance! :)
This part of your create statement might cause problems
KEY_EVENTS_COLOR + "TEXT," + KEY_EVENTS_START_DATE + "DATE,"
+ KEY_EVENTS_END_DATE + "TEXT" + ")"
You are missing a space before TEXT everywhere :)

Categories