Android SQLite - 删除时使用错误的列并重新创建具有相同表名的表

时间:2017-03-30 17:06:30

标签: java android sqlite

我正在编写一个使用SQLite的Android应用。但是我发现在重新创建具有相同表名的表时获取SELECT结果列的问题。以下是代码段:

package com.info.abc;

import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.util.Log;

import java.util.ArrayList;



public class TestActivity2 extends Activity {

    private static final String TAG = TestActivity2.class.getSimpleName();

    public SQLiteDatabase mDataBase;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        String mPath = Main.DB_PATH + "test.db";

        Log.e(TAG, ">>>>>>>> in openDB " + mPath);


        mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.CREATE_IF_NECESSARY);


        gosql("DROP TABLE IF EXISTS TT1");

        gosql("CREATE TABLE TT1 ('STAFFID' varchar, 'STAFFNAME' varchar)");
        getDbTableDetail("TT1");

        gosql("INSERT INTO TT1 ('STAFFID', 'STAFFNAME') VALUES ('999', 'Tim')");
        gosql("SELECT * FROM TT1");

        gosql("DROP TABLE IF EXISTS TT1");  // Empty result

        // Drop table and Re-create with different column name
        getDbTableDetail("TT1");

        gosql("CREATE TABLE TT1 ('FIRSTNAME' varchar, 'LASTNAME' varchar)");
        getDbTableDetail("TT1");

        gosql("INSERT INTO TT1 ('FIRSTNAME', 'LASTNAME') VALUES ('F', 'L')");
        gosql("SELECT * FROM TT1");



        mDataBase.close();

    }


    public void getDbTableDetail(String table) {
        Cursor c = mDataBase.rawQuery(
                "SELECT * FROM sqlite_master WHERE name='" + table + "'", null);
        int i = 0;

        Log.e(TAG, "getDbTableDetail() - " + table);
        for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
            String[] temp = new String[c.getColumnCount()];
            for (i = 0; i < temp.length; i++) {
                temp[i] = c.getString(i);

                Log.e(TAG, "c.getColumnNames() = " + c.getColumnNames()[i] + ", temp[i] = " + temp[i]);

            }

        }

    }


    public synchronized void gosql(String sql)
    {
        Log.e(TAG, "gosql() = " + sql);

        Cursor result = null;


        if (sql.startsWith("SELECT"))
        {
            try {
                result=mDataBase.rawQuery(sql, null);

                Log.e(TAG, "SQL result");
                result.moveToFirst();
                do {
                    for (int i=0; i<result.getColumnNames().length; i++)
                    {
                        Log.e(TAG, result.getColumnNames()[i] + " = " +result.getString((result.getColumnIndex(result.getColumnNames()[i]))) );
                    }
                    Log.e(TAG, " ");

                }while(result.moveToNext());

                result.close();
            } catch (Exception e) {
                Log.e(TAG, "gosql SELECT error:");
                Log.e(TAG, e.toString());
            } finally {


            }
        }
        else
        {
            try {
                mDataBase.execSQL(sql);


            } catch (Exception e) {
                Log.e(TAG, "gosql execSQL error:");
                Log.e(TAG, e.toString());
            } finally {
            }
        }
    }
}

这是Logcat输出:

gosql() = DROP TABLE IF EXISTS TT1
gosql() = CREATE TABLE TT1 ('STAFFID' varchar, 'STAFFNAME' varchar)

getDbTableDetail() - TT1
c.getColumnNames() = type, temp[i] = table
c.getColumnNames() = name, temp[i] = TT1
c.getColumnNames() = tbl_name, temp[i] = TT1
c.getColumnNames() = rootpage, temp[i] = 4
c.getColumnNames() = sql, temp[i] = CREATE TABLE TT1 ('STAFFID' varchar, 'STAFFNAME' varchar)

gosql() = INSERT INTO TT1 ('STAFFID', 'STAFFNAME') VALUES ('999', 'Tim')

gosql() = SELECT * FROM TT1
SQL result
STAFFID = 999
STAFFNAME = Tim

gosql() = DROP TABLE IF EXISTS TT1

getDbTableDetail() - TT1

gosql() = CREATE TABLE TT1 ('FIRSTNAME' varchar, 'LASTNAME' varchar)

getDbTableDetail() - TT1
c.getColumnNames() = type, temp[i] = table
c.getColumnNames() = name, temp[i] = TT1
c.getColumnNames() = tbl_name, temp[i] = TT1
c.getColumnNames() = rootpage, temp[i] = 4
c.getColumnNames() = sql, temp[i] = CREATE TABLE TT1 ('FIRSTNAME' varchar, 'LASTNAME' varchar)

gosql() = INSERT INTO TT1 ('FIRSTNAME', 'LASTNAME') VALUES ('F', 'L')
gosql() = SELECT * FROM TT1
SQL result
STAFFID = F
STAFFNAME = L

显然,第二个SELECT结果返回带有WRONG COLUMN NAME的数据,而getColumnIndex()不能按预期工作。我花了一整天的时间试图弄清楚它有什么不对,但没有运气。

是否无法使用相同的表重新创建表(具有正确的列名)?

请帮助,谢谢!

1 个答案:

答案 0 :(得分:0)

简短答案

  • 尝试禁用WAL(预写日志)模式
  • 对于“选择”查询,尝试显式枚举列

详细信息

我遇到了类似的问题,启用了WAL并且我的情况是这样的:

  1. 删除表格X
  2. 创建具有不同列集的表X
  3. 进行db.query(X,null,null,...)调用(请注意,第二个arg(“列”)为null)
  4. 问题:在cursor.getColumnNames()调用上生成的光标为我提供了旧列名列表-好像根本没有执行drop + create一样!但是大约1-2分钟后,getColumnNames()给出了正确的列集。

然后,如果我禁用WAL模式,cursor.getColumnNames()会立即为我提供正确的列。

我也尝试再次启用WAL,但是通过传递所有列的列表(db.query(X,arrayOf(C1,C2,...),null,null,...))来修改查询-它也为我工作