I'm struggling with the following exception:
android.database.CursorWindowAllocationException
android.database.CursorWindow.<init>(CursorWindow.java:104)
android.database.AbstractWindowedCursor.clearOrCreateWindow(AbstractWindowedCursor.java:198)
android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:162)
android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:156)
android.database.AbstractCursor.moveToPosition(AbstractCursor.java:161)
android.database.AbstractCursor.moveToFirst(AbstractCursor.java:201)
com.hyperlearning.library.Learning.getTotalScore(Learning.java:301)
...
I have the following code:
public int getTotalScore(String categoryCode, int from, int to) {
int repeat = Options.getInt(activity.getString(R.string.repeat_to_learn_key), 10);
String sql =
"select " +
"sum(w1.enabled*w1.score), " +
"sum((1-w1.enabled)*"+repeat+") " +
"from words1 as w1 " +
"join categories_words1 as cw on cw.word1_id = w1.id " +
"join categories as ct on ct.id = cw.category_id " +
"WHERE ct.name = '" + categoryCode + "' AND cw.position BETWEEN " + from + " AND " + to;
Cursor cursor = db.rawQuery(sql, null);
try {
cursor.moveToFirst(); // *** Line 301 ***
return cursor.getInt(0) + cursor.getInt(1);
} finally {
cursor.close();
}
}
The error occurs mainly on Kindle Fire HD.
Related
So, I am currently using the DragSortListView with a SQLite database. I want to resort my database whenever im dragging an item of the ListView to a new position. Therefore I wrote a piece of code that should manage it. But if I'm moving something from a position below to a higher one, it is strangely sorted. I already looked on this code for hours and asked some friends, but I never found the solution.
Code
Method in the DatabaseHelper
public void moveValues(int from, int to, String sammlung){
SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
System.out.println(from + " - " + to);
if(from < to){
//This part is working properly
Cursor cursor = sqLiteDatabase.rawQuery("SELECT ID FROM " + TABLE_NAME + " WHERE POSITION IS " + "\"" + from + "\" AND SAMMLUNG IS " + "\"" + sammlung + "\"", null);
for (int i = from+1; i < to+1; i++){
switchPositionValue(i, i-1);
}
ContentValues contentValues = new ContentValues();
contentValues.put(COLUMN_5, to);
cursor.moveToFirst();
sqLiteDatabase.update(TABLE_NAME, contentValues, "ID=?", new String[]{cursor.getInt(0)+""});
cursor.close();
}else{
//This is the not working part
Cursor cursor = sqLiteDatabase.rawQuery("SELECT ID FROM " + TABLE_NAME + " WHERE POSITION IS " + "\"" + from + "\" AND SAMMLUNG IS " + "\"" + sammlung + "\"", null);
for (int i = from-1; i > to-1; i--){
switchPositionValue(i, i+1);
}
ContentValues contentValues = new ContentValues();
contentValues.put(COLUMN_5, to);
cursor.moveToFirst();
System.out.println(cursor.getInt(0));
//The next line destroys it. But I dont know how to fix it or what exactly is not working
sqLiteDatabase.update(TABLE_NAME, contentValues, "ID=?", new String[]{cursor.getInt(0)+""});
cursor.close();
}
}
The parameters are:
from: The position it's taken away from
to: The position it's taken to
sammlung: I saving all the items of different collections in one database. So it's only there to sort out only specific items.
Method to change the value of a row with a specific position
public void switchPositionValue(int before, int after){
SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COLUMN_5, after);
sqLiteDatabase.update(TABLE_NAME, contentValues, "POSITION=?", new String[]{before+""});
}
Demonstration
So if you've got any idea why its behaving this strange or do know a better approach to moving a row in a database, I would really appreciate your help.
Android other way SQL one (COLUMN_5 is POSITION column)
public void moveValues(int from, int to) {
SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
String query =
"WITH p(from_position,to_position,max_position,min_position) AS (" +
"SELECT " +
"?," +
"?," +
"(SELECT max(" + COLUMN_5 + ") FROM " + TABLE_NAME + ")," +
"(SELECT min(" + COLUMN_5 + ") FROM " + TABLE_NAME + ")), " +
"updates AS(" +
"SELECT " + TABLE_NAME + ".id," + COLUMN_5 + " AS current, " + COLUMN_5 + " + 1 AS proposed " +
"FROM " + TABLE_NAME + " " +
"WHERE " + COLUMN_5 + " >= (SELECT to_position FROM p) " +
"AND " + COLUMN_5 + " < (SELECT from_position FROM p) " +
"UNION SELECT " + TABLE_NAME + ".id," + COLUMN_5 + " AS current, " + COLUMN_5 + " -1 AS proposed " +
"FROM " + TABLE_NAME + " " +
"WHERE " + COLUMN_5 + " <= (SELECT to_position FROM p) " +
"AND " + COLUMN_5 + " > (SELECT from_position FROM p) " +
"UNION SELECT " + TABLE_NAME + ".id," + COLUMN_5 + ",(SELECT to_position FROM p) " +
"FROM " + TABLE_NAME + " " +
"WHERE " + COLUMN_5 + " = (SELECT from_position FROM p) " +
"AND (SELECT from_position FROM p) <> (SELECT to_position FROM p)" +
"), " +
"finish_updates AS (" +
"SELECT * FROM updates " +
"WHERE max((SELECT from_position FROM p),(SELECT to_position FROM p)) <= (SELECT max_position FROM p) " +
"AND min((SELECT from_position FROM p),(SELECT to_position FROM p)) >= (SELECT min_position FROM p)" +
")" +
"UPDATE " + TABLE_NAME + " SET " + COLUMN_5 + " = " +
"(" +
" SELECT proposed " +
" FROM finish_updates " +
" WHERE finish_updates.id = " + TABLE_NAME + ".id" +
") " +
"WHERE " + TABLE_NAME + ".id IN " +
"(" +
" SELECT id FROM finish_updates" +
");";
SQLiteStatement stmnt = sqLiteDatabase.compileStatement(query);
stmnt.bindLong(1,from);
stmnt.bindLong(2,to);
stmnt.executeUpdateDelete();
}
fiddle test SQL at
These are the fields in table.
public static String Table_Train_Demo = "SMS_TRAIN_DEMO";
public static String Train_DEMO_ID = "TRAIN_DEMO_ID";
public static String Train_Person_Name = "PERSON_NAME";
public static String Train_Designation = "DESIGNATION";
public static String Train_Status = "STATUS";
public static String Train_Station_Or_Place_ID = "STATION_OR_PLACE_ID";
public static String Train_Discussion_ID = "DISCUSSION_ID";
public static String Train_EMP_Status_ID = "EMP_STATUS_ID";
public static String Train_Demo_Plan_ID = "DEMO_PLAN_ID";
public static String Train_APP_Plan_ID = "APP_PLAN_ID";
public static String Train_Pk = "SMS_TRAIN_DEMO_pk";
public static String Train_Constraint =
"SMS_TRAIN_DEMO_SMS_EMP_DAILY_STATUS";
public static String Train_Plan_Constraint =
"SMS_TRAIN_DEMO_SMS_PLAN_TRAIN_DEMO";
public static String Train_App_Plan_Constraint =
"SMS_TRAIN_DEMO_SMS_PLAN_APP";
This is the create statement of the table
private static final String Create_Table_Train_Demo = "CREATE TABLE " +
Table_Train_Demo + " ("
+ Train_DEMO_ID + " INTEGER NOT NULL CONSTRAINT " + Train_Pk + "
PRIMARY KEY AUTOINCREMENT, "
+ Train_Person_Name + " TEXT NOT NULL, "
+ Train_Designation + " TEXT NOT NULL, "
+ Train_Status + " INTEGER NOT NULL, "
+ Train_Station_Or_Place_ID + " INTEGER ,"
+ Train_Discussion_ID + " INTEGER NOT NULL ,"
+ Train_EMP_Status_ID + " INTEGER NOT NULL ,"
+ Train_Demo_Plan_ID + " INTEGER NOT NULL ,"
+ Train_APP_Plan_ID + " INTEGER NOT NULL ,"
+ " CONSTRAINT " + Train_Constraint + " FOREIGN KEY (" +
Train_EMP_Status_ID + ")"
+ " REFERENCES " + Table_Daily_EmpStatus + "(" + EStatus_ID + ")"
+ " CONSTRAINT " + Train_Plan_Constraint + " FOREIGN KEY (" +
Train_Demo_Plan_ID + ")"
+ " REFERENCES " + Table_Plan_Train_Demo + "(" + PTrain_Demo_Plan_ID
+ ")"
+ " CONSTRAINT " + Train_App_Plan_Constraint + " FOREIGN KEY (" +
Train_APP_Plan_ID + ")"
+ " REFERENCES " + Table_Plan_App + "(" + PAPP_Plan_ID + ")"
+ ")";
Here I am trying to insert values to the table.
public boolean addTrngDemoEntryRecord(TRN_DEMOS recInfo, long StatusEntryID,
long PID) {
SQLiteDatabase db = null;
try {
db = this.getWritableDatabase();
if (db.isOpen()) {
ContentValues values = new ContentValues();
if (recInfo != null) {
values.put(Train_Demo_Plan_ID,PID);
values.put(Train_APP_Plan_ID,PID);
values.put(Train_EMP_Status_ID,StatusEntryID);
values.put(Train_Person_Name, recInfo.PNAME);
values.put(Train_Designation, recInfo.DESG);
values.put(Train_Status, recInfo.STATUS);
values.put(Train_Discussion_ID, recInfo.DID);
values.put(Train_Station_Or_Place_ID,0);
}
long row_id = db.insert(Table_Train_Demo, null, values);
if (row_id == -1) {
return false;
} else {
return true;
}
} else
return false;
}catch (Exception e) {
Log.d("eEmp/TrngDemoplan", "Excdeption Occurred due to " +
e.toString());
return false;
} finally {
if (db != null)
db.close();
}
}
Noexceptions are coming while table creation.
But while inserting data into the table
long row_id = db.insert(Table_Train_Demo, null, values);
row_id = -1 is coming and returns false value.
what might be the problem. I am new to android.
Any help would be appreciated.
log these values recInfo.PNAME, recInfo.DESG, recInfo.STATUS and recInfo.DID
as these values can't be null.
for a try just used hardcoded values
values.put(Train_Person_Name, "xyz");
values.put(Train_Designation, "xyz");
values.put(Train_Status, "xyz");
values.put(Train_Discussion_ID,"xyz");
and check the value of row_id.
I've written a method that searches the database to find matching lecturers depending on modules. However, when I run this, it saves the same name for all three!
Here is the method:
public List<tableModules> getStudentsLecturers(String mod1, String mod2, String mod3) {
List<tableModules> studentModuleLecturer = new ArrayList<tableModules>();
// Select All Query to find lecturers depending on modules
Log.d("Lecturers", mod1);
Log.d("Lecturers", mod2);
Log.d("Lecturers", mod3);
String selectQuery = "SELECT DISTINCT " + Module_Lecturer + " FROM " + Table2 + " WHERE " + Module_Name + " = \'" + mod1 + "\' OR \'" + mod2 + "\' OR \'" + mod3 + "\'";
Log.d("1", "1");
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
tableModules moduleLecturers = new tableModules();
moduleLecturers.modulelecturer = cursor.getString(0);
studentModuleLecturer.add(moduleLecturers);
} while (cursor.moveToNext());
}
// return lecture list
return studentModuleLecturer;
}
Which is then called here in MainActivity.java
List<tableModules> lecturers = db.getStudentsLecturers(mod1, mod2, mod3);
if (!lecturers.isEmpty())
{
for (tableModules session: lecturers)
{
Editor editor = preferences.edit();
//Save lecturers to list
for (int i=0; i < lecturers.size(); i++) {
if (counter == 0)
{
lecturer1 = session.modulelecturer.toString();
editor.putString("lec1", lecturer1);
Log.d("Lecs", "1");
editor.commit();
counter++;
}
if (counter == 1)
{
lecturer2 = session.modulelecturer.toString();
editor.putString("lec2", lecturer2);
Log.d("Lecs", "2");
editor.commit();
counter++;
}
if (counter == 2)
{
lecturer3 = session.modulelecturer.toString();
editor.putString("lec3", lecturer3);
Log.d("Lecs", "3");
editor.commit();
counter++;
}
else
{
Log.d("Lecs", "ERROR");
}
}
I get that I'm saving the same "session.modulelecturer.toString();" to each, but I can't figure out how to alter the SQL method to select all three lecturers for all three seperate modules.
Try replacing
" WHERE " + Module_Name + " = \'" + mod1 + "\' OR \'" + mod2 + "\' OR \'" + mod3 + "\'";
with
" WHERE " + Module_Name + " = '" + mod1 + "' OR " + Module_Name + " = '" + mod2 + "' OR " + Module_Name + " = '" + mod3 + "'";
In practice, you can't say
WHERE ModuleName = 'This' OR 'That'
but you can say
WHERE ModuleName = 'This' OR ModuleName = 'That'
I know it's a drag to rewrite the column name for each possible value, but it's how it works in SQL.
Alternatively, you can write a more compact form:
WHERE ModuleName IN ('This', 'That', '...')
So you query can become:
" WHERE " + Module_Name + " IN ('" + mod1 + "', '" + mod2 + "', '" + mod3 + "')";
I am trying to create an insertion in some tables with random data but i have a problem with the duplicates.
I wrote an insertion of random records in postgresql b but it returns duplicates detection and there should be no duplicates i am using every name for exactly 2680 times and the names are 22 for 58960 records total of table play_in please check and tell what's wrong with it and how does produce a duplicate.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.util.Random;
public class PostgreSQLJDBC {
public static void main(String args[]) {
Connection c = null;
Statement stmt = null;
int year;
int year1;
int num_rating;
int num_ratingAvg;
String[] round = new String[5];
round[0] = "32nd";
round[1] = "16th";
round[2] = "quarter_final";
round[3] = "SemiFinal";
round[4] = "FInal";
String[] name1 = new String[22];
name1[0] = "ahmed";
name1[1] = "mohamed";
name1[2] = "mai";
name1[3] = "salma";
name1[4] = "walid";
name1[5] = "wael";
name1[6] = "fadwa";
name1[7] = "nada";
name1[8] = "nahla";
name1[9] = "mustafa";
name1[10] = "ola";
name1[11] = "omar";
name1[12] = "amr";
name1[13] = "beshoy";
name1[14] = "marina";
name1[15] = "gerges";
name1[16] = "botros";
name1[17] = "mina";
name1[18] = "menna";
name1[19] = "feasal";
name1[20] = "youssef";
name1[21] = "moussa";
Random id = new Random();
Random roundc = new Random();
String round1;
int idc;
String name;
Random namec = new Random();
int namecounter = 0;
Random belle = new Random();
int belec = 0;
Random yearc = new Random();
Random num_ratingsc = new Random();
int num_ratingSum = 0;
// roundc.nextInt(4);
try {
Class.forName("org.postgresql.Driver");
c = DriverManager.getConnection(
"jdbc:postgresql://localhost:5432/a2", "mohamed", "1234");
System.out.println("Opened database successfully");
String sql3;
String sql4;
stmt = c.createStatement();
String sql = "CREATE TABLE cup_matches "
+ "(MID INT PRIMARY KEY NOT NULL,"
+ " ROUND TEXT NOT NULL, "
+ " YEAR INT NOT NULL, "
+ " NUM_RATINGS INT NOT NULL, "
+ " RATING INT NOT NULL)";
String sql1 = "CREATE TABLE played_in "
+ "(MID INT NOT NULL,"
+ " NAME TEXT NOT NULL, "
+ " YEAR INT NOT NULL, "
+ " POSITION INT NOT NULL, "
+ "CONSTRAINT pk_played_in PRIMARY KEY (MID, NAME));";
String sql2 = "ALTER TABLE played_in ADD CONSTRAINT ref FOREIGN KEY (MID) REFERENCES cup_matches (MID);";
stmt.executeUpdate(sql);
stmt.executeUpdate(sql1);
stmt.executeUpdate(sql2);
for (int i = 0; i < 2680; i++) {
year = yearc.nextInt(2014 - 1900) + 1900;
num_rating = num_ratingsc.nextInt(1000);
num_ratingSum += num_rating;
num_ratingAvg = num_ratingSum / (i + 1);
round1 = "\'" + round[roundc.nextInt(4)] + "\'";
sql3 = "INSERT INTO cup_matches (MID, ROUND, YEAR, NUM_RATINGS, RATING) "
+ "VALUES ("
+ i
+ ", "
+ round1
+ ", "
+ year
+ ", "
+ num_rating + ", " + num_ratingAvg + ");";
stmt.executeUpdate(sql3);
System.out.println(sql3);
}
for (int j = 0; j < 58960; j++) {
idc = j;
idc = (idc >= 2679) ? 0 : idc;
year1 = yearc.nextInt(2014 - 1900) + 1900;
num_rating = num_ratingsc.nextInt(1000);
if ((belle.nextInt(2 - 1) + 1) == 1 && belec < 118) {
name = "\'" + name1[namecounter] + "belle" + "\'";
sql4 = "INSERT INTO played_in (MID, NAME, YEAR, POSITION) "
+ "VALUES (" + idc + ", " + name + ", " + year1
+ ", " + num_rating + ");";
stmt.executeUpdate(sql4);
belec++;
idc++;
System.out.println(idc + " " + namecounter);
namecounter++;
} else {
name = "\'" + name1[namecounter] + "\'";
sql4 = "INSERT INTO played_in (MID, NAME, YEAR, POSITION) "
+ "VALUES (" + idc + ", " + name + ", " + year1
+ ", " + num_rating + ");";
stmt.executeUpdate(sql4);
namecounter++;
idc++;
System.out.println(idc + " " + namecounter);
}
namecounter = (namecounter < 22) ? namecounter : 0;
}
// stmt.executeUpdate(sql);
// stmt.executeUpdate();
// stmt.executeUpdate(sql2);
stmt.close();
c.close();
} catch (Exception e) {
System.err.println(e.getClass().getName() + ": " + e.getMessage());
System.exit(0);
}
System.out.println("Table created successfully");
}
}
This line:
idc = (idc >= 2679) ? 0 : idc;
is causing you problems as you later use idc as the value for mid, which is your primary key. This line returns 0 when idc is >= 2679, which will give you duplicate key errors.
This line makes idc = 0 for each j value above 2679.
idc = j;
idc = (idc >= 2679) ? 0 : idc;
The first time, it will insert in the table played_in with idc = 0 and will insert that value for each name, when the name counter starts again with 0:
namecounter = (namecounter < 22) ? namecounter : 0;
It will try to insert the first name with 0 again and it will fail due to duplicate key error
I have a method getstaffinfo, which has 3 parameter (var_1, connection, filewriter fw), the var_1 value is read from a text file. So the method will be called as many times based on all the var_1 value passed from text file . approx ( 15000)
public static String getstaffid(String var_1, Connection connection,
FileWriter fw) throws SQLException, Exception
// Create a statement
{
String record = null;
ResultSet rs = null;
Statement stmt = connection.createStatement();
boolean empty = true;
try {
rs = stmt
.executeQuery("select username, firstname, lastname, middlename, street, city, stateorprovince, ziporpostalcode, countryorregion, fax, phone, extension, mobile, pager, title, primaryemail, secondaryemail, officename, description, comments, suspendeddate, userdata, employeeid, createuser, updateuser, createdate, updatedate, employeetype, servicedeskticketnumber, startdate, enddate, manager, businessapprover, technicalapprover, delegate, location, jobcodes, customproperty1, customproperty2, customproperty3, customproperty4, customproperty5, customproperty6, customproperty7, customproperty8, customproperty9, customproperty10 from globalusers where username = '"+ var_1 + "'");
ResultSetMetaData metaData = rs.getMetaData();
int columns = metaData.getColumnCount();
ArrayList<String> records = new ArrayList<String>();
while (rs.next()) {
empty = false;
//record = rs.getString(1) + " " + rs.getString(2) + " " + rs.getString(3) + " " + rs.getString(4) + " " + rs.getString(5) + " " + rs.getString(6) + " " + rs.getString(7) + " " + rs.getString(8) + " " + rs.getString(9) + " " + rs.getString(10) + " " + rs.getString(11) + " " + rs.getString(12) + " " + rs.getString(13) + " " + rs.getString(14) + " " + rs.getString(15) + " " + rs.getString(16) + " " + rs.getString(17) + " " + rs.getString(18) + " " + rs.getString(19) + " " + rs.getString(20) + " " + rs.getString(21) + " " + rs.getString(22) + " " + rs.getString(23) + " " + rs.getString(24) + " " + rs.getString(25) + " " + rs.getString(26) + " " + rs.getString(27) + " " + rs.getString(28) + " " + rs.getString(29) + " " + rs.getString(30) + " " + rs.getString(31) + " " + rs.getString(32) + " " + rs.getString(33) + " " + rs.getString(34) + " " + rs.getString(35) + " " + rs.getString(36) + " " + rs.getString(37) + " " + rs.getString(38) + " " + rs.getString(39) + " " + rs.getString(40) + " " + rs.getString(41) + " " + rs.getString(42) + " " + rs.getString(43) + " " + rs.getString(44) + " " + rs.getString(45) + " " + rs.getString(46) + " " + rs.getString(47);
for (int i = 1; i <= columns; i++) {
String value = rs.getString(i);
records.add(value);
}
for (int j = 0; j < records.size(); j++) {
record = records.get(j) + ",";
}
fw.append(record);
}
/*fw.append(rs.getString(1));
fw.append(',');
fw.append(rs.getString(2));
fw.append(',');
fw.append(rs.getString(3));
fw.append('\n'); */
} finally {
fw.flush();
rs.close();
stmt.close();
}
return record;
}
As you can see, am executing a query for 47 values, which could be null or it can have some value.
Then i iterate through this 47 column, take the value and store it to an array list. Then i iterate the array list and write all the values to the string record with comma seperated value. Which is written to a csv file.
But it does not work fine. Any inputs would be appreciated...
You may have already solved the problem. Just let you know that I tried to use your code just now and found the issue was here:
record = records.get(j) + ",";
You should use something like this:
record = record + records.get(j) + ",";
Also change String to StringBuffer will improve the performance.
You didn't write the exact problem you face, but there is one for sure: you never write a line break into the file, so all data gets in one line.
while (rs.next()) {
... // your code, with the for loops
fw.append(record); //writing out the line, from your code
fw.append("\r\n"); //line break -- add this line
} //this is the end of the "while(rs.next())" loop
...