【问题标题】:Creating tables with consecutive number via method通过方法创建具有连续编号的表
【发布时间】:2017-11-30 11:16:32
【问题描述】:

我想建立一个 GPS 数据库,其中每个表代表一次旅行。 为此,有必要通过按一个按钮来创建一个新表。

到目前为止,我已经完成了所有工作。

但我希望根据这种模式显示表格: 行程_1;行程_2; Trip_3 ...

但我总是收到表名为空的错误消息。

android.database.sqlite.SQLiteException: near "Table": syntax error (code 1): , while compiling: CREATE TABLE Trip_ (ID INTEGER PRIMARY KEY, Table TEXT)

请帮我找出我的错误。

这是我的数据库类:

public class GPSDatabase extends SQLiteOpenHelper {

String TAG = "GPSDatabase";

int tnumber = 0;


public static GPSDatabase INSTANCE = null;

private static final String DB_NAME              = "eelo";
private static final int    VERSION              = 1;
public  static       String TABLE_NAME           = "Trip_0";
public  static final String TABLE_TRIP           = "Trip_";

public  static final String TABLE_COLUMN         = "Table";

public  static final String ID_COLUMN            = "ID";
public  static final String NUMBER_COLUMN        = "Number";
public  static final String DISTANCE_COLUMN      = "Distance";
public  static final String LATITUDE_COLUMN      = "Latitude";
public  static final String LONGITUDE_COLUMN     = "Longitude";


private GPSDatabase(Context context) {
    super(context, DB_NAME, null, VERSION);
}


public static GPSDatabase getInstance (final Context context){
    if (INSTANCE == null){
        INSTANCE = new GPSDatabase(context);
    }
    return INSTANCE;
}

@Override
public void onCreate(SQLiteDatabase db) {


    String createTripQuery =
                "CREATE TABLE " + TABLE_TRIP + " (" + ID_COLUMN + " INTEGER PRIMARY KEY, " + TABLE_COLUMN + " TEXT)";

    String createQuery;
    if (tnumber==0) {
        createQuery =
                "CREATE TABLE " + TABLE_NAME + " (" + ID_COLUMN + " INTEGER PRIMARY KEY, " + NUMBER_COLUMN + " INTEGER DEFAULT NULL, " + DISTANCE_COLUMN + " INTEGER DEFAULT NULL, " + LATITUDE_COLUMN + " REAL DEFAULT NULL, " + LONGITUDE_COLUMN + " REAL DEFAULT NULL)";
    }
    else{
        createQuery =
                "CREATE TABLE " + getTrip(tnumber) + " (" + ID_COLUMN + " INTEGER PRIMARY KEY, " + NUMBER_COLUMN + " INTEGER DEFAULT NULL, " + DISTANCE_COLUMN + " INTEGER DEFAULT NULL, " + LATITUDE_COLUMN + " REAL DEFAULT NULL, " + LONGITUDE_COLUMN + " REAL DEFAULT NULL)";
    }
    db.execSQL(createTripQuery);
    db.execSQL(createQuery);
    Log.d(TAG, "Table created");
    tnumber++;

}

在这里我得到了新旅行的表名:

public String getTrip(final long id) {

    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.query(TABLE_TRIP, new String[]{ID_COLUMN, TABLE_COLUMN}, ID_COLUMN + " = ?", new String[]{String.valueOf(id)}, null, null, null);

    String table = null;

    if (cursor != null && cursor.getCount() > 0) {
        cursor.moveToFirst();

        table = cursor.getString(cursor.getColumnIndex(TABLE_COLUMN));

    }

    Log.d(TAG, "getTable: "+table);
    return table;
}

这是来自 Main Activity 的 ONCLICK-Methode;

public static GPSDatabase db;
public static int tripNumber = 0;
public static boolean clicked=false;
int NAV = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {

...

    db = GPSDatabase.getInstance(this);

...

    Button btn= (Button)findViewById(R.id.button3);
    btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            Log.d("new Trip ","clicked");
            tripNumber++;

            long newID = -1;

            try{
                SQLiteDatabase database = db.getWritableDatabase();

                ContentValues values = new ContentValues();

                values.put(db.TABLE_COLUMN, "Trip_"+tripNumber);

                newID = database.insert(db.TABLE_TRIP, null, values);

            }catch (SQLiteException e){
                Log.e(TAG,"insert");
            }finally {
                Log.d(TAG,"TableTrip insert with ID " + newID);
            }

            SQLiteDatabase db1;
            db1 = db.getWritableDatabase();
            db.TABLE_NAME = db.TABLE_TRIP+tripNumber;
            String dropTable = "DROP TABLE IF EXISTS " + (db.TABLE_NAME+(tripNumber-1));
            db1.execSQL(dropTable);
            String createQuery =
                    "CREATE TABLE " + db.TABLE_NAME + " (" + db.ID_COLUMN + " INTEGER PRIMARY KEY, " + db.NUMBER_COLUMN + " INTEGER DEFAULT NULL, " + db.DISTANCE_COLUMN + " INTEGER DEFAULT NULL, " + db.LATITUDE_COLUMN + " REAL DEFAULT NULL, " + db.LONGITUDE_COLUMN + " REAL DEFAULT NULL)";


            db1.execSQL(createQuery);
        }
    });
}

【问题讨论】:

  • table 是不能用作列名的关键字。那就是语法问题。一个更大的问题是,您真的不应该像那样对数据进行建模 - 不要动态创建新表,而是保持表架构固定并将可变部分(例如行程 ID)作为数据放入。
  • 好的谢谢我改造了
  • @TominB 实际上,如果您真的想要,您可以将 table 作为列名。您可以将其括在单引号、双引号、方括号或坟墓中。根据SQLite Keywords

标签: android mysql sqlite android-sqlite


【解决方案1】:

问题在于在public static final String TABLE_COLUMN = "Table"; 中将该列命名为Table。 SQLite 假设它遇到了语法错误的关键字 TABLE。

如果你真的想要一个名为 Table 的列,这是可能的,你可以使用public static final String TABLE_COLUMN = "'Table'"; 。但是,这仍然可能存在问题和混乱。

你也可以使用_yourcolumnname来避免使用推荐的(但相对很少使用)

SQLite 在接受新关键字时会不时添加新关键字 特征。所以为了防止你的代码被未来破坏 您通常应该引用任何标识符 英语单词,即使您不必这样做。[强调添加]

更多信息SQLite Keywords

所以也许public static final String TABLE_COLUMN = "_Table";

但是,也许更好的解决方案是应用规范化(减少数据库冗余)并使用一个包含一列的表来标识行程,而不是使用多个结构相同的表。

例如你可以使用:-

private static final String DB_NAME              = "eelo";
private static final int    VERSION              = 1;
public  static final String TABLE_TRIP           = "Trip_";

public  static final String ID_COLUMN            = "ID";
public  static final String NUMBER_COLUMN        = "Number";
public  static final String DISTANCE_COLUMN      = "Distance";
public  static final String LATITUDE_COLUMN      = "Latitude";
public  static final String LONGITUDE_COLUMN     = "Longitude";
public  static final String TRIP_COLUMN          = "Trip";

然后您将只需要在 onCreate 方法中没有逻辑的单个表创建语句,例如可能是:-

@Override
public void onCreate(SQLiteDatabase db) {

    String createQuery =
                "CREATE TABLE " + TABLE_NAME + " (" + 
                    ID_COLUMN + " INTEGER PRIMARY KEY, " + 
                    NUMBER_COLUMN + " INTEGER DEFAULT NULL, " +
                    DISTANCE_COLUMN + " INTEGER DEFAULT NULL, " +
                    LATITUDE_COLUMN + " REAL DEFAULT NULL, " +
                    LONGITUDE_COLUMN + " REAL DEFAULT NULL +
                    TRIP_COLUMN + "INTEGER" +
                    )";
    }
    db.execSQL(createQuery);
    Log.d(TAG, "Table created");
}

然后您不需要getTrip 来交换表,而只需使用WHERE trip = respective_trip_as_int(注意 int 可能很长,因此很可能是足够的数字)来实现相同的最终结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-17
    • 1970-01-01
    • 1970-01-01
    • 2017-10-05
    • 2010-09-09
    • 2021-11-26
    • 2018-11-10
    相关资源
    最近更新 更多