SQLite返回的行数为零

时间:2022-10-20 11:40:56
   public class SQLiteProvider extends SQLiteOpenHelper {

    private static SQLiteDatabase sqliteDatabase ;  

    public SQLiteProvider ( Context context ) {
        super ( context , DATABASE_NAME , null , DATABASE_VERSION ) ;
    }

    @Override
    public void onCreate ( SQLiteDatabase sqliteDatabase ) {
        try {
            this . sqliteDatabase = this . getWriteabaleDataBase ( ) ;
            this . sqliteDatabase . execSQL ( TABLE_CREATE ) ;
            this . sqliteDatabase . close ( ) ;
        } catch ( Exception exception ) {
            Log . i ( LOG_TAG , "Exception is `" + exception . toString ( ) + "`" ) ;
        }
    }

    private void insert ( String column1Value , String column2Value ) {
        try {
            sqliteDatabase = this . getWritableDatabase ( ) ;
            sqliteDatabase . execSQL ( QUERY_TO_INSERT ) ;
            sqliteDatabase . close ( ) ;
        } catch ( Exception exception ) {
            Log . i ( LOG_TAG , "Exception is `" + exception . toString ( ) + "`" ) ;
        }
    }

    private String selectColumn1byColumn2 ( String column2Value ) {
        try {
            sqliteDatabase . getWritableDatabase ( ) ;
            cursor = sqliteDatabase . rawQuery ( SELECT_QUERY ) ;
            sqliteDatabase . close ( )
        } catch ( Exception exception ) {
            Log . i ( LOG_TAG , "Exception is `" + exception . toString ( ) + "`" ) ;
        }
        if ( cursor . getCount ( ) > 0 ) {
            return cursor . getString ( 0 ) ;
        } else { 
            Log . i ( LOG_TAG , "selectColumn1byColumn2 row count is zero " ) ; 
            return "";
        }
    }

    public String doIt ( ) {
        insert ( VARIABLE1 , VARIABLE2 ) ;
        return selectColumn1byColumn2 ( VARIABLE2 ) ;
    }
}

All methods use same sqliteDatabase object and each of it calls getWritableDatabase in the beginning. Function doIt ( ) return just empty string and Log that row count is zero ( selectColumn1byColumn2 row count is zero ) and no one exception. I do it with transaction and without , both of it does not work How do I it right?

所有方法都使用相同的sqliteDatabase对象,并且每个方法都在开头调用getWritableDatabase。函数doIt()只返回空字符串并且Log该行计数为零(selectColumn1byColumn2行计数为零)并且没有一个例外。我是用交易做的,没有,两者都不起作用我怎么做对了?

update April 8

4月8日更新

I have done

我已经做好了

Add finally block with sqliteDatabase . close ( )

使用sqliteDatabase添加finally块。关 ( )

Add cursor . close ( ) when it necessary before sqliteDatabase . close ( )

添加光标。在sqliteDatabase之前必要时关闭()。关 ( )

Change cursor . getString ( 0 ) to cursor . getString ( cursor . getColumnIndex ( TABLE_COLUMN1 ) )

改变光标。 getString(0)到游标。 getString(cursor.getColumnIndex(TABLE_COLUMN1))

Change if ( cursor . getCount ( ) > 0 ) to if ( cursor . moveToFirst ( ) )

将if(cursor.getCount()> 0)更改为if(cursor.moveToFirst())

And now it returns row count is zero and don`t work on Jelly Bean 4.2 - android application crashes

现在它返回行数为零,并且不会在Jelly Bean 4.2上运行 - 安卓应用程序崩溃

2 个解决方案

#1


1  

The reason why you are not getting the desired result is because you are closing the database first and then reading from the cursor.

您没有得到所需结果的原因是您先关闭数据库然后从光标读取。

If you first read from the cursur, and when you are finished using the cursor close your database, it should work.

如果您第一次从cursur读取,并且当您使用光标关闭数据库时,它应该可以工作。

The user named alibi gives a good explanation in his answer: Clicky

名为alibi的用户在他的回答中给出了一个很好的解释:Clicky

1) The cursor is just a pointer to the data returned by your query, it doesn't contain all the data from your query. This is to increase performance/efficiency (large resultsets aren't read at once -> less memory used). Therefore, if you close the database, the cursor can't retrieve the data -> it's empty.

1)游标只是指向查询返回的数据的指针,它不包含查询中的所有数据。这是为了提高性能/效率(不会立即读取大型结果集 - >使用的内存更少)。因此,如果关闭数据库,则游标无法检索数据 - >它是空的。

2) When you close a cursor, all associated resources are released -> you can't access the data associated with this cursor (since it has been released), but you can make new queries using this or other cursors. When you close a database, you can't query it anymore (until you re-open it).

2)当您关闭游标时,将释放所有相关资源 - >您无法访问与此游标关联的数据(因为它已被释放),但您可以使用此游标或其他游标进行新查询。当您关闭数据库时,您不能再查询它(直到您重新打开它)。

3) Always close cursors. Otherwise you will run into problems - the GC will complain if the cursor isn't closed and new queries are blocked.

3)始终关闭游标。否则您将遇到问题 - 如果光标未关闭且新查询被阻止,GC将会抱怨。

4) If you close it when your app finishes, yes

4)如果你的应用程序完成后关闭它,是的

again, credit goes to alibi.

再次,功劳归于不在犯罪现场。

UPDATE

private String selectColumn1byColumn2 ( String column2Value ) {
    try {
        sqliteDatabase . getWritableDatabase ( ) ;
        cursor = sqliteDatabase . rawQuery ( SELECT_QUERY ) ;

        cursor.moveToFirst();
        if ( cursor . getCount ( ) > 0 ) {
            return cursor . getString ( 0 ) ;
        } else { 
            Log . i ( LOG_TAG , "selectColumn1byColumn2 row count is zero " ) ; 
            return "";
        }
    } catch ( Exception exception ) {
        Log . i ( LOG_TAG , "Exception is `" + exception . toString ( ) + "`" ) ;
    } finally {
        cursor.close(); 
        sqliteDatabase . close ( );
    }
}

cursor.close and sqliteDatabase.close() are moved to a finally block. This will ensure the database and cursor gets cleaned up properly when you are done using it.

cursor.close和sqliteDatabase.close()被移动到finally块。这样可以确保在使用完数据库和光标后正确清理它。

Also I added a cursor.moveToFirst(); call before your first call to getCount();

我还添加了一个cursor.moveToFirst();在第一次调用getCount()之前调用;

Not 100% sure it's needed but it's worth a try.

不是100%肯定它是必要的,但它值得一试。

#2


1  

Change your selectColumn1byColumn2() method as folllows

将selectColumn1byColumn2()方法更改为folllows

 private String selectColumn1byColumn2 ( String column2Value ) {
        try {
            sqliteDatabase . getWritableDatabase ( ) ;
            cursor = sqliteDatabase . rawQuery ( SELECT_QUERY ) ;
             if ( cursor . getCount ( ) > 0 ) {
            return cursor . getString ( 0 ) ;
        } else { 
            Log . i ( LOG_TAG , "selectColumn1byColumn2 row count is zero " ) ; 
            return "";
          }

sqliteDatabase . close ( );

sqliteDatabase。关 ( );

        } catch ( Exception exception ) {
            Log . i ( LOG_TAG , "Exception is `" + exception . toString ( ) + "`" ) ;
        }
         finally
        {
          cursor.close();
          sqliteDatabase . close ( );
        }

#1


1  

The reason why you are not getting the desired result is because you are closing the database first and then reading from the cursor.

您没有得到所需结果的原因是您先关闭数据库然后从光标读取。

If you first read from the cursur, and when you are finished using the cursor close your database, it should work.

如果您第一次从cursur读取,并且当您使用光标关闭数据库时,它应该可以工作。

The user named alibi gives a good explanation in his answer: Clicky

名为alibi的用户在他的回答中给出了一个很好的解释:Clicky

1) The cursor is just a pointer to the data returned by your query, it doesn't contain all the data from your query. This is to increase performance/efficiency (large resultsets aren't read at once -> less memory used). Therefore, if you close the database, the cursor can't retrieve the data -> it's empty.

1)游标只是指向查询返回的数据的指针,它不包含查询中的所有数据。这是为了提高性能/效率(不会立即读取大型结果集 - >使用的内存更少)。因此,如果关闭数据库,则游标无法检索数据 - >它是空的。

2) When you close a cursor, all associated resources are released -> you can't access the data associated with this cursor (since it has been released), but you can make new queries using this or other cursors. When you close a database, you can't query it anymore (until you re-open it).

2)当您关闭游标时,将释放所有相关资源 - >您无法访问与此游标关联的数据(因为它已被释放),但您可以使用此游标或其他游标进行新查询。当您关闭数据库时,您不能再查询它(直到您重新打开它)。

3) Always close cursors. Otherwise you will run into problems - the GC will complain if the cursor isn't closed and new queries are blocked.

3)始终关闭游标。否则您将遇到问题 - 如果光标未关闭且新查询被阻止,GC将会抱怨。

4) If you close it when your app finishes, yes

4)如果你的应用程序完成后关闭它,是的

again, credit goes to alibi.

再次,功劳归于不在犯罪现场。

UPDATE

private String selectColumn1byColumn2 ( String column2Value ) {
    try {
        sqliteDatabase . getWritableDatabase ( ) ;
        cursor = sqliteDatabase . rawQuery ( SELECT_QUERY ) ;

        cursor.moveToFirst();
        if ( cursor . getCount ( ) > 0 ) {
            return cursor . getString ( 0 ) ;
        } else { 
            Log . i ( LOG_TAG , "selectColumn1byColumn2 row count is zero " ) ; 
            return "";
        }
    } catch ( Exception exception ) {
        Log . i ( LOG_TAG , "Exception is `" + exception . toString ( ) + "`" ) ;
    } finally {
        cursor.close(); 
        sqliteDatabase . close ( );
    }
}

cursor.close and sqliteDatabase.close() are moved to a finally block. This will ensure the database and cursor gets cleaned up properly when you are done using it.

cursor.close和sqliteDatabase.close()被移动到finally块。这样可以确保在使用完数据库和光标后正确清理它。

Also I added a cursor.moveToFirst(); call before your first call to getCount();

我还添加了一个cursor.moveToFirst();在第一次调用getCount()之前调用;

Not 100% sure it's needed but it's worth a try.

不是100%肯定它是必要的,但它值得一试。

#2


1  

Change your selectColumn1byColumn2() method as folllows

将selectColumn1byColumn2()方法更改为folllows

 private String selectColumn1byColumn2 ( String column2Value ) {
        try {
            sqliteDatabase . getWritableDatabase ( ) ;
            cursor = sqliteDatabase . rawQuery ( SELECT_QUERY ) ;
             if ( cursor . getCount ( ) > 0 ) {
            return cursor . getString ( 0 ) ;
        } else { 
            Log . i ( LOG_TAG , "selectColumn1byColumn2 row count is zero " ) ; 
            return "";
          }

sqliteDatabase . close ( );

sqliteDatabase。关 ( );

        } catch ( Exception exception ) {
            Log . i ( LOG_TAG , "Exception is `" + exception . toString ( ) + "`" ) ;
        }
         finally
        {
          cursor.close();
          sqliteDatabase . close ( );
        }