是否有任何方法可以解决常见的SQLite问题? [英] Are there any methods that assist with resolving common SQLite issues?

查看:80
本文介绍了是否有任何方法可以解决常见的SQLite问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通常,相对简单的错误会导致问题,而这些错误往往由于对SQLite的误解而变得更加复杂.

It is often that relatively simple errors cause issues often compounded by a misunderstanding of SQLite.

例如:-

    找不到
  • 表和列,因为通常假定DBHelperonCreate方法(SQLiteOpenHelper类的子类)在每次创建DBHelper实例或每次运行App时都运行. (注意!onCreate仅在首次创建数据库时自动调用,然后仅在尝试使用SQLiteDatabase getReadableDatabasegetWriteableDatabse方法之一的情况下才自动调用,如果更改数据库结构/模式,然后有3种简单的方式强制onCreate运行,a)清除应用程序的数据,b)卸载应用程序,或b)如果onUpgrade方法调用onCreate方法(在删除表之后) ),然后增加数据库版本号).
  • 插入/更新无效,但不会失败.
  • tables and columns not found because it is often assumed that the onCreate method of a DBHelper (subclass of the SQLiteOpenHelper class) runs every time an instance of the DBHelper is created or every time the App is run. (Note! onCreate is only automatically invoked when a Database is first created and then only when an attempt is made to use one of the SQLiteDatabase getReadableDatabase or getWriteableDatabse methods, if changing the database structure/schema then there are 3 simple ways of forcing onCreate to run, a) Clear the App's Data, b) uninstall the App or b) if the onUpgrade method invokes the onCreate method (after dropping the table(s)) then increase the Database Version Number).
  • Inserts/Updates not working but not failing.

对于SQLite的新手来说,也很生气/令人生畏,无法立即查看数据库包含的内容.

For the novice to SQLite it can also be infuriating/daunting not being able to readily see what the database contains.

那么有什么通用的工具可以帮助您吗?

So are there any common utilities that can assist?

注意!这旨在成为共享知识Q的问题&样式.

推荐答案

以下是一些新手可能会发现有用的常用实用程序,它们被设计为非特定的并且可以在任何数据库/表上使用.

The following are some common utilities that the novice might find helpful, they are designed to be non-specific and work on any database/table.

当前有以下潜在有用的方法:-

Currently there are the following potentially useful methods:-

  • getAllRowsFromTable 来检索所有行的游标.
  • logCursorColumns ,将游标中的列写入日志.
  • logCursorData 将游标数据和列写入日志.

注意!肯定会考虑添加/修正的要求/建议.

Note! Requests/suggestions for additions/amendments will definitely be considered.

此外,以上使用了某些方法,或者用于测试/创建以上方法:-

Additionally there are some methods used by the above or were used for testing/creating the above :-

  • getEmptyColumnLessCursor (使用此方法需要 100分 :)).
  • getBytedata 返回给定字节数组的十六进制字符串(用于BLOB处理).
  • convertBytesToHex 将字节数组转换为十六进制字符串(用于BLOB处理).
  • getEmptyColumnLessCursor (100 points for a use of this method :) ).
  • getBytedata to return a hex string of the given byte array (for BLOB handling).
  • convertBytesToHex to convert a byte array into a hex string (for BLOB handling).

预期的用途是创建一个游标,随后由logCursorColumnslogCursorData方法检查该游标.不应在生产应用程序中使用它(不是,不能这样).

The intended use is for creating a cursor to subsequently be examined by the logCursorColumns and logCursorData methods. This should not be used in a production App (not that it can't be).

具有签名:-

public static Cursor getAllRowsFromTable(
                                  SQLiteDatabase db,
                                  String tablename,
                                  boolean use_error_checking,
                                  String forceRowidAs)

其中:-

  • 第一个参数是SQLite数据库(由于通用性质而需要).
  • 第二个参数是从中获取数据的表名.
  • 第三个参数(如果为true)将在创建光标写入日志(如果表不在数据库中)之前检查表是否存在.
  • 第四个参数(如果不为null或长度> 0的字符串)将创建一个附加列,该列根据该参数命名,并包含ROWID的内容(旨在在未提供ROWID别名的情况下提供帮助,因此ROWID不包括在内). 什么是ROWID?
  • The first parameter is the SQLite Database (required due to the generic nature).
  • The second parameter is the table name from which to get the data.
  • The third parameter, if true will check if the table exists before creating the cursor writing to the log if the table is not in the database.
  • The fourth parameter, if not null or if a string of length > 0, will create an additional column, named according to the parameter with the contents of the ROWID (intended for assisting when no alias for ROWID has been provided and hence ROWID is not included). What's ROWID??
    mEventsDBHelper = new EventsDBHelper(this);


    // Get all rows from table (this exist or should do)
    Cursor events = CommonSQLiteUtilities.getAllRowsFromTable(
            mEventsDBHelper.getEventsDB(),
            EventsDBHelper.TBNAME,
            CommonSQLiteUtilities.ERROR_CHECKING_ON,
            null
    );

    // Deisgned to be problematic i.e. no such table        
    Cursor ooops = CommonSQLiteUtilities.getAllRowsFromTable(
            mEventsDBHelper.getEventsDB(),
            "NOTATABLE",
            CommonSQLiteUtilities.ERROR_CHECKING_ON,
            "rumplestiltskin"
    );

  • 第二次调用将在日志的以下行中显示:-

    • The second invocation results in the following line in the log:-

      D/SQLITE_CSU: Table NOTATABLE was not located in the SQLite Database Master Table.
      

    • 尽管Cursor可能没有行也没有列(例如,在表不在数据库中的情况下),但总是会返回Cursor.

    • A Cursor will always be returned although that Cursor may have no rows and no columns (e.g. in the case where the table was not in the database).

      查询数据库表(如果是)时,将捕获并报告异常.例如,将 IS 指定为第四个参数(有效尝试使用SQLIte不喜欢的ROWID AS IS,将导致类似于:-

      Exceptions are trapped and reported on when the database table is queried (if it is). e.g specifying IS as the 4th parameter (effectively trying to use ROWID AS IS, which SQLIte doesn't like, will result in something similar to :-

      10-09 18:57:52.591 3835-3835/? E/SQLiteLog: (1) near "IS": syntax error
      10-09 18:57:52.592 3835-3835/? D/SQLITE_CSU: Exception encountered but trapped when querying table events Message was: 
                                                   near "IS": syntax error (code 1): , while compiling: SELECT rowid AS  IS , * FROM events
      10-09 18:57:52.592 3835-3835/? D/SQLITE_CSU: Stacktrace was:
      10-09 18:57:52.592 3835-3835/? W/System.err: android.database.sqlite.SQLiteException: near "IS": syntax error (code 1): , while compiling: SELECT rowid AS  IS , * FROM events
      10-09 18:57:52.592 3835-3835/? W/System.err:     at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
      10-09 18:57:52.592 3835-3835/? W/System.err:     at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
      10-09 18:57:52.592 3835-3835/? W/System.err:     at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
      10-09 18:57:52.592 3835-3835/? W/System.err:     at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
      10-09 18:57:52.592 3835-3835/? W/System.err:     at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
      10-09 18:57:52.592 3835-3835/? W/System.err:     at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
      10-09 18:57:52.592 3835-3835/? W/System.err:     at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
      10-09 18:57:52.592 3835-3835/? W/System.err:     at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1316)
      10-09 18:57:52.592 3835-3835/? W/System.err:     at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1163)
      10-09 18:57:52.592 3835-3835/? W/System.err:     at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1034)
      10-09 18:57:52.592 3835-3835/? W/System.err:     at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1202)
      10-09 18:57:52.592 3835-3835/? W/System.err:     at mjt.sqlitedbexamples.CommonSQLiteUtilities.getAllRowsFromTable(CommonSQLiteUtilities.java:97)
      10-09 18:57:52.592 3835-3835/? W/System.err:     at mjt.sqlitedbexamples.MainActivity.onCreate(MainActivity.java:61)
      10-09 18:57:52.593 3835-3835/? W/System.err:     at android.app.Activity.performCreate(Activity.java:5990)
      10-09 18:57:52.593 3835-3835/? W/System.err:     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
      10-09 18:57:52.593 3835-3835/? W/System.err:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
      10-09 18:57:52.593 3835-3835/? W/System.err:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
      10-09 18:57:52.593 3835-3835/? W/System.err:     at android.app.ActivityThread.access$800(ActivityThread.java:151)
      10-09 18:57:52.593 3835-3835/? W/System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
      10-09 18:57:52.593 3835-3835/? W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:102)
      10-09 18:57:52.593 3835-3835/? W/System.err:     at android.os.Looper.loop(Looper.java:135)
      10-09 18:57:52.593 3835-3835/? W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:5254)
      10-09 18:57:52.593 3835-3835/? W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
      10-09 18:57:52.593 3835-3835/? W/System.err:     at java.lang.reflect.Method.invoke(Method.java:372)
      10-09 18:57:52.593 3835-3835/? W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
      10-09 18:57:52.593 3835-3835/? W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
      

      • 返回的游标将为空,没有行或列.
      • 旨在用于编写有关游标的列信息(通常会反映数据库,尤其是在使用getAllRowsFromTable的情况下).

        Is intended to be used to write column information about a cursor (which would normally reflect the database, especially if using getAllRowsFromTable).

        具有签名:-

            public static void logCursorColumns(Cursor csr)
        

        其中:-

        • 第一个参数是游标(任何游标).

        注意!在上一个示例之后.

            CommonSQLiteUtilities.logCursorColumns(events);
            CommonSQLiteUtilities.logCursorColumns(ooops);
        

        这将导致以下输出:-

        10-09 18:57:52.593 3835-3835/? D/SQLITE_CSU: logCursorColumns invoked. Cursor has the following 8 columns.
        10-09 18:57:52.593 3835-3835/? D/SQLITE_CSU: Column Name 1 is _id
        10-09 18:57:52.593 3835-3835/? D/SQLITE_CSU: Column Name 2 is starts
        10-09 18:57:52.593 3835-3835/? D/SQLITE_CSU: Column Name 3 is starts_timestamp
        10-09 18:57:52.593 3835-3835/? D/SQLITE_CSU: Column Name 4 is ends
        10-09 18:57:52.593 3835-3835/? D/SQLITE_CSU: Column Name 5 is ends_timestamp
        10-09 18:57:52.593 3835-3835/? D/SQLITE_CSU: Column Name 6 is description
        10-09 18:57:52.593 3835-3835/? D/SQLITE_CSU: Column Name 7 is counter
        10-09 18:57:52.593 3835-3835/? D/SQLITE_CSU: Column Name 8 is bytedata
        10-09 18:57:52.593 3835-3835/? D/SQLITE_CSU: logCursorColumns invoked. Cursor has the following 0 columns.
        


        logCursorData

        这与logCursorColumns非常相似,不同之处在于它提供了更广泛的信息重排列,并且还提供了对存储在数据库中的实际数据进行重排的信息.


        logCursorData

        This is very similar to logCursorColumns other than it provides more extensive information regrading columns and that it also provides information regrading the actual data stored in the database.

        具有签名:-

            public static void logCursorData(Cursor csr)
        

        其中:-

        • 第一个参数是游标(任何游标).

        注意!在上一个示例之后.

            CommonSQLiteUtilities.logCursorData(events);
            CommonSQLiteUtilities.logCursorData(ooops);
        

        这将导致以下输出:-

        10-09 19:30:31.801 1455-1455/? D/SQLITE_CSU: logCursorData Cursor has 6 rows with 8 columns.
        10-09 19:30:31.801 1455-1455/? D/SQLITE_CSU: Information for row 1 offset=0
                                                        For Column _id Type is INTEGER value as String is 1 value as long is 1 value as double is 1.0
                                                        For Column starts Type is INTEGER value as String is 1507537831 value as long is 1507537831 value as double is 1.507537831E9
                                                        For Column starts_timestamp Type is INTEGER value as String is 1507537831783 value as long is 1507537831783 value as double is 1.507537831783E12
                                                        For Column ends Type is INTEGER value as String is 0 value as long is 0 value as double is 0.0
                                                        For Column ends_timestamp Type is INTEGER value as String is 0 value as long is 0 value as double is 0.0
                                                        For Column description Type is STRING value as String is TESTEVENT 001 just description value as long is 0 value as double is 0.0
                                                        For Column counter Type is INTEGER value as String is 0 value as long is 0 value as double is 0.0
                                                        For Column bytedata Type is BLOB value as String is unobtainable! value as long is unobtainable! value as double is unobtainable! value as blob is 00000000
        10-09 19:30:31.802 1455-1455/? D/SQLITE_CSU: Information for row 2 offset=1
                                                        For Column _id Type is INTEGER value as String is 2 value as long is 2 value as double is 2.0
                                                        For Column starts Type is INTEGER value as String is 1507537831 value as long is 1507537831 value as double is 1.507537831E9
                                                        For Column starts_timestamp Type is INTEGER value as String is 1507537831785 value as long is 1507537831785 value as double is 1.507537831785E12
                                                        For Column ends Type is INTEGER value as String is 0 value as long is 0 value as double is 0.0
                                                        For Column ends_timestamp Type is INTEGER value as String is 0 value as long is 0 value as double is 0.0
                                                        For Column description Type is STRING value as String is TESTEVENT 002 description and bytearray value as long is 0 value as double is 0.0
                                                        For Column counter Type is INTEGER value as String is 0 value as long is 0 value as double is 0.0
                                                        For Column bytedata Type is BLOB value as String is unobtainable! value as long is unobtainable! value as double is unobtainable! value as blob is 0001020304050607080900
        10-09 19:30:31.802 1455-1455/? D/SQLITE_CSU: Information for row 3 offset=2
                                                        For Column _id Type is INTEGER value as String is 3 value as long is 3 value as double is 3.0
                                                        For Column starts Type is INTEGER value as String is 1507537831 value as long is 1507537831 value as double is 1.507537831E9
                                                        For Column starts_timestamp Type is INTEGER value as String is 1507537831789 value as long is 1507537831789 value as double is 1.507537831789E12
                                                        For Column ends Type is INTEGER value as String is 15254678 value as long is 15254678 value as double is 1.5254678E7
                                                        For Column ends_timestamp Type is INTEGER value as String is 0 value as long is 0 value as double is 0.0
                                                        For Column description Type is STRING value as String is TESTEVENT 003 desc, bytes and endint value as long is 0 value as double is 0.0
                                                        For Column counter Type is INTEGER value as String is 0 value as long is 0 value as double is 0.0
                                                        For Column bytedata Type is BLOB value as String is unobtainable! value as long is unobtainable! value as double is unobtainable! value as blob is 7F7E7D7C
        10-09 19:30:31.802 1455-1455/? D/SQLITE_CSU: Information for row 4 offset=3
                                                        For Column _id Type is INTEGER value as String is 4 value as long is 4 value as double is 4.0
                                                        For Column starts Type is INTEGER value as String is 1507537831 value as long is 1507537831 value as double is 1.507537831E9
                                                        For Column starts_timestamp Type is INTEGER value as String is 1507537831792 value as long is 1507537831792 value as double is 1.507537831792E12
                                                        For Column ends Type is INTEGER value as String is 0 value as long is 0 value as double is 0.0
                                                        For Column ends_timestamp Type is INTEGER value as String is 0 value as long is 0 value as double is 0.0
                                                        For Column description Type is STRING value as String is TESTEVENT 004 desc, bytes and endlong value as long is 0 value as double is 0.0
                                                        For Column counter Type is INTEGER value as String is 0 value as long is 0 value as double is 0.0
                                                        For Column bytedata Type is BLOB value as String is unobtainable! value as long is unobtainable! value as double is unobtainable! value as blob is 38424C56606A747E
        10-09 19:30:31.803 1455-1455/? D/SQLITE_CSU: Information for row 5 offset=4
                                                        For Column _id Type is INTEGER value as String is 5 value as long is 5 value as double is 5.0
                                                        For Column starts Type is INTEGER value as String is 1507537831 value as long is 1507537831 value as double is 1.507537831E9
                                                        For Column starts_timestamp Type is INTEGER value as String is 1507537831794 value as long is 1507537831794 value as double is 1.507537831794E12
                                                        For Column ends Type is INTEGER value as String is 1699999999 value as long is 1699999999 value as double is 1.699999999E9
                                                        For Column ends_timestamp Type is INTEGER value as String is 0 value as long is 0 value as double is 0.0
                                                        For Column description Type is STRING value as String is TESTEVENT 005 desc, endint value as long is 0 value as double is 0.0
                                                        For Column counter Type is INTEGER value as String is 0 value as long is 0 value as double is 0.0
                                                        For Column bytedata Type is BLOB value as String is unobtainable! value as long is unobtainable! value as double is unobtainable! value as blob is 00000000
        10-09 19:30:31.803 1455-1455/? D/SQLITE_CSU: Information for row 6 offset=5
                                                        For Column _id Type is INTEGER value as String is 6 value as long is 6 value as double is 6.0
                                                        For Column starts Type is INTEGER value as String is 1507537831 value as long is 1507537831 value as double is 1.507537831E9
                                                        For Column starts_timestamp Type is INTEGER value as String is 1507537831796 value as long is 1507537831796 value as double is 1.507537831796E12
                                                        For Column ends Type is INTEGER value as String is 0 value as long is 0 value as double is 0.0
                                                        For Column ends_timestamp Type is INTEGER value as String is 0 value as long is 0 value as double is 0.0
                                                        For Column description Type is STRING value as String is TESTEVENT 006 desc, endlong value as long is 0 value as double is 0.0
                                                        For Column counter Type is INTEGER value as String is 0 value as long is 0 value as double is 0.0
                                                        For Column bytedata Type is BLOB value as String is unobtainable! value as long is unobtainable! value as double is unobtainable! value as blob is 00000000
        

        并为空的光标(糟糕):-

        and for the empty Cursor (ooops) :-

        10-09 19:30:31.804 1455-1455/? D/SQLITE_CSU: logCursorData Cursor has 0 rows with 0 columns.
        

        代码CommonSQLiteUtilities.java:-

        public class CommonSQLiteUtilities {
        
            public static final boolean ERROR_CHECKING_ON = true;
            public static final boolean ERROR_CHECKING_OFF = false;
        
            // SQLite MASTER TABLE definitions
            static final String SQLITE_MASTER = "sqlite_master";
            static final String SM_TABLE_TYPE_COLUMN = "type";
            static final String SM_NAME_COLUMN = "name";
            static final String SM_TABLENAME_COLUMN = "tbl_name";
            static final String SM_ROOTPAGE_COLUMN = "rootpage";
            static final String SM_SQL_COLUMN = "sql";
            static final String SM_TYPE_TABLE = "table";
            static final String SM_TYPE_INDEX = "index";
        
        
            static final String CSU_TAG = "SQLITE_CSU";
        
            private CommonSQLiteUtilities() {}
        
            /**
             * Generic get all rows from an SQlite table,
             * allowing the existence of the table to be checked and also
             * allowing the ROWID to be added AS a supplied string
             *
             * @param db                    The SQLiteDatabase
             * @param tablename             The name of the table from which the
             *                              returned cursor will be created from;
             *                              Note!
             * @param use_error_checking    Whether ot not to try to detect errors
             *                              currently just table doesn't exist,
             *                              true to turn on, false to turn off
             *                              ERROR_CHECKING_ON = true
             *                              ERROR_CHECKING_OFF = false
             * @param forceRowidAs          If length of string passed is 1 or greater
             *                              then a column, as an alias of ROWID, will be
             *                              added to the cursor
             * @return                      the extracted cursor, or in the case of the
             *                              underlying table not existing an empty cursor
             *                              with no columns
             */
            public static Cursor getAllRowsFromTable(SQLiteDatabase db,
                                              String tablename,
                                              boolean use_error_checking,
                                              String forceRowidAs) {
                String[] columns = null;
        
                // Tablename must be at least 1 character in length
                if (tablename.length() < 1) {
                    Log.d(CSU_TAG,new Object(){}.getClass().getEnclosingMethod().getName() +
                            " is finishing as the provided tablename is less than 1 character in length"
                    );
                    return new MatrixCursor(new String[]{});
                }
        
                // If use_error_checking is true then check that the table exists
                // in the sqlite_master table
                if (use_error_checking) {
                    Cursor chkcsr = db.query(SQLITE_MASTER,null,
                            SM_TABLE_TYPE_COLUMN + "=? AND "
                                    + SM_TABLENAME_COLUMN + "=?",
                            new String[]{SM_TYPE_TABLE,tablename},
                            null,null,null
                    );
        
                    // Ooops table is not in the Database so return an empty
                    // column-less cursor
                    if (chkcsr.getCount() < 1) {
                        Log.d(CSU_TAG,"Table " + tablename +
                                " was not located in the SQLite Database Master Table."
                        );
                        // return empty cursor with no columns
                        return new MatrixCursor(new String[]{});
        
                    }
                    chkcsr.close();
                }
        
                // If forcing an alias of ROWID then user ROWID AS ???, *
                if(forceRowidAs != null && forceRowidAs.length() > 0) {
                    columns = new String[]{"rowid AS " +forceRowidAs,"*"};
                }
        
                // Finally return the Cursor but trap any exceptions
                try {
                    return db.query(tablename, columns, null, null, null, null, null);
                } catch (Exception e) {
                    Log.d(CSU_TAG,"Exception encountered but trapped when querying table " + tablename +
                            " Message was: \n" + e.getMessage());
                    Log.d(CSU_TAG,"Stacktrace was:");
                    e.printStackTrace();
                    return new MatrixCursor(new String[]{});
                }
            }
        
            /**
             * Create and return a Cursor devoid of any rows and columns
             * Not used, prehaps of very little use.
             * @param db    The Sqlite database in which the cursor is to be created
             * @return      The empty Cursor
             */
            private static Cursor getEmptyColumnLessCursor(SQLiteDatabase db) {
                return new MatrixCursor(new String[]{});
            }
        
            /**
             * Write column names in the passed Cursor to the log
             * @param csr   The Cursor to be inspected.
             */
            public static void logCursorColumns(Cursor csr) {
                Log.d(CSU_TAG,
                        new Object(){}.getClass().getEnclosingMethod().getName() +
                                " invoked. Cursor has the following " +
                                Integer.toString(csr.getColumnCount())+
                                " columns.");
                int position = 0;
                for (String column: csr.getColumnNames()) {
                    position++;
                    Log.d(CSU_TAG,"Column Name " +
                            Integer.toString(position) +
                            " is "
                            + column
                    );
                }
            }
        
            /**
             * Write the contents of the Cursor to the log
             * @param csr   The Cursor that is to be displayed in the log
             */
            public static void logCursorData(Cursor csr) {
                int columncount = csr.getColumnCount();
                int rowcount = csr.getCount();
                int csrpos = csr.getPosition(); //<<< added 20171016 to
                Log.d(CSU_TAG,
                        new Object(){}.getClass().getEnclosingMethod().getName() +
                                " Cursor has " +
                                Integer.toString(rowcount) +
                                " rows with " +
                                Integer.toString(columncount) + " columns."
                );
                csr.moveToPosition(-1);     //Ensure that all rows are retrieved <<< added 20171016
                while (csr.moveToNext()) {
                    String unobtainable = "unobtainable!";
                    String logstr = "Information for row " + Integer.toString(csr.getPosition() + 1) + " offset=" + Integer.toString(csr.getPosition());
                    for (int i=0; i < columncount;i++) {
                        logstr = logstr + "\n\tFor Column " + csr.getColumnName(i);
                        switch (csr.getType(i)) {
                            case Cursor.FIELD_TYPE_NULL:
                                logstr = logstr + " Type is NULL";
                                break;
                            case Cursor.FIELD_TYPE_FLOAT:
                                logstr = logstr + "Type is FLOAT";
                                break;
                            case Cursor.FIELD_TYPE_INTEGER:
                                logstr = logstr + " Type is INTEGER";
                                break;
                            case Cursor.FIELD_TYPE_STRING:
                                logstr = logstr + " Type is STRING";
                                break;
                            case Cursor.FIELD_TYPE_BLOB:
                                logstr = logstr + " Type is BLOB";
                                break;
                        }
                        String strval_log = " value as String is ";
                        String lngval_log = " value as long is ";
                        String dblval_log = " value as double is ";
                        String blbval_log = "";
                        try {
                            strval_log = strval_log + csr.getString(i);
                            lngval_log = lngval_log + csr.getLong(i);
                            dblval_log = dblval_log +  csr.getDouble(i);
                        } catch (Exception e) {
                            strval_log = strval_log + unobtainable;
                            lngval_log = lngval_log + unobtainable;
                            dblval_log = dblval_log + unobtainable;
                            try {
                                blbval_log = " value as blob is " +
                                        getBytedata(csr.getBlob(i),24);
                            } catch (Exception e2) {
                                e2.printStackTrace();
                            }
        
                        }
                        logstr = logstr + strval_log + lngval_log + dblval_log + blbval_log;
                    }
                    Log.d(CSU_TAG,logstr);
                }
                csr.moveToPosition(csrpos); // restore cursor position <<< added 20171016
            }
        
            /**
             * Return a hex string of the given byte array
             * @param bytes     The byte array to be converted to a hexadecimal string
             * @param limit     the maximum number of bytes;
             *                  note returned string will be up to twice as long
             * @return          The byte array represented as a hexadecimal string
             */
            private static String getBytedata(byte[] bytes, int limit) {
                if (bytes.length < limit) {
                    return convertBytesToHex(bytes);
                } else {
                    byte[] subset = new byte[limit];
                    System.arraycopy(bytes,0,subset,0,limit);
                    return convertBytesToHex(subset);
                }
            }
        
            // HEX characters as a char array for use by convertBytesToHex
            private final static char[] hexarray = "0123456789ABCDEF".toCharArray();
        
            /**
             * Return a hexadecimal string representation of the passed byte array
             * @param bytes     The byte array to be represented.
             * @return          The string representing the byte array as hexadecimal
             */
            private static String convertBytesToHex(byte[] bytes) {
                char[] hexstr = new char[bytes.length * 2];
                for (int i=0; i < bytes.length; i++) {
                    int h = bytes[i] & 0xFF;
                    hexstr[i * 2] = hexarray[h >>> 4];
                    hexstr[i * 2 + 1] = hexarray[h & 0xF];
                }
                return new String(hexstr);
            }
        }
        

        要使用该代码,只需创建 CommonSQLiteUtilities 类并复制上面的代码.

        To use the code simply create the CommonSQLiteUtilities class and copy the code above.

        这篇关于是否有任何方法可以解决常见的SQLite问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆