sql >> Database >  >> RDS >> SQLite

Zijn er methoden die helpen bij het oplossen van veelvoorkomende SQLite-problemen?

De volgende zijn enkele veelvoorkomende hulpprogramma's die de beginner misschien nuttig vindt, ze zijn ontworpen om niet-specifiek te zijn en werken op elke database/tabel.

Momenteel zijn er de volgende potentieel bruikbare methoden:-

  • getAllRowsFromTable om een ​​cursor met alle rijen op te halen.
  • logCursorColumns om de kolommen in een cursor naar het logboek te schrijven.
  • logCursorData om de cursorgegevens en kolommen naar het logboek te schrijven.

Opmerking! Verzoeken/suggesties voor aanvullingen/wijzigingen zullen zeker in overweging worden genomen.

Daarnaast zijn er enkele methoden die door het bovenstaande zijn gebruikt of zijn gebruikt voor het testen/creëren van het bovenstaande:-

  • getEmptyColumnLessCursor (100 punten voor het gebruik van deze methode :) ).
  • getBytedata om een ​​hexadecimale tekenreeks van de opgegeven byte-array terug te geven (voor BLOB-verwerking).
  • convertBytesToHex om een ​​bytearray om te zetten in een hex-tekenreeks (voor BLOB-verwerking).

getAllRowsFromTable

Het beoogde gebruik is voor het maken van een cursor die vervolgens wordt onderzocht door de logCursorColumns en logCursorData methoden. Dit mag niet worden gebruikt in een productie-app (niet dat het niet kan).

Dit heeft de handtekening:-

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

Waar:-

  • De eerste parameter is de SQLite Database (vereist vanwege het generieke karakter).
  • De tweede parameter is de tabelnaam waaruit de gegevens moeten worden gehaald.
  • De derde parameter, indien waar, controleert of de tabel bestaat voordat de cursor wordt gemaakt die naar het logboek schrijft als de tabel niet in de database staat.
  • De vierde parameter, indien niet null of een string met een lengte> 0, zal een extra kolom creëren, genoemd volgens de parameter met de inhoud van de ROWID (bedoeld om te helpen wanneer er geen alias voor ROWID is opgegeven en dus ROWID is niet inbegrepen). Wat is ROWID??

Voorbeeld van gebruik:-

    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"
    );
  • De tweede aanroep resulteert in de volgende regel in het logboek:-

    D/SQLITE_CSU: Table NOTATABLE was not located in the SQLite Database Master Table.
    
  • Er wordt altijd een cursor geretourneerd, hoewel die cursor mogelijk geen rijen en geen kolommen heeft (bijvoorbeeld in het geval dat de tabel niet in de database stond).

  • Uitzonderingen worden opgevangen en gerapporteerd wanneer de databasetabel wordt opgevraagd (als dit het geval is). bijv. specificeren van IS als de 4e parameter (effectief proberen om ROWID AS IS te gebruiken) , waar SQLIte niet van houdt, zal resulteren in iets dat lijkt op :-

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)
  • De geretourneerde cursor is leeg zonder rijen of kolommen.

logCursorColumns

Is bedoeld om te worden gebruikt om kolominformatie over een cursor te schrijven (die normaal gesproken de database weerspiegelt, vooral bij gebruik van getAllRowsFromTable ).

Dit heeft de handtekening:-

    public static void logCursorColumns(Cursor csr)

Waar:-

  • De eerste parameter is een cursor (elke cursor).

Voorbeeld gebruik:-

Opmerking! In vervolg op het vorige voorbeeld.

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

Dit zal resulteren in output in de trant van:-

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

Dit lijkt erg op logCursorColumns behalve dat het uitgebreidere kolommen voor herindeling van informatie biedt en dat het ook informatie biedt die de feitelijke gegevens die in de database zijn opgeslagen, herschikt.

Dit heeft de handtekening:-

    public static void logCursorData(Cursor csr)

Waar:-

  • De eerste parameter is een cursor (elke cursor).

Voorbeeld gebruik:-

Opmerking! In vervolg op het vorige voorbeeld.

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

Dit zal resulteren in output in de trant van:-

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

en voor de lege cursor (oeps) :-

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

De code 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);
    }
}

Om de code te gebruiken, maakt u gewoon de CommonSQLiteUtilities class en kopieer de bovenstaande code.



  1. Cumulatief totaal aantal gebruikers per dag in MySQL krijgen

  2. Kan ik de naam krijgen van alle tabellen van de SQL Server-database in de C#-toepassing?

  3. Hoe de REGEX_REPLACE()-functie werkt in MySQL

  4. Hoe FOR XML PATH('') werkt bij het aaneenschakelen van rijen