SQLiteException:靠近“categories”:语法错误(代码1):

时间:2015-11-17 19:59:55

标签: android sqlite

我的TABLE_NAME的“类别”似乎有些不对劲,但我可能错了。

我所知道的是,我收到了这个错误,还有其他一些错误。我花了几个小时在这个改变代码上无济于事。请参阅logcat和下面的类。

我希望有更多经验的SQLite可以指出我正确的方向:)

感谢您的时间。

logcat的:

11-17 13:55:55.556 6903-6966/com.example.michael.budgetapp E/SQLiteLog: (1) near "categories": syntax error
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime: Process: com.example.michael.budgetapp, PID: 6903
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime: java.lang.RuntimeException: An error occured while executing doInBackground()
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime:     at android.os.AsyncTask$3.done(AsyncTask.java:304)
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime:     at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime:     at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime:     at java.util.concurrent.FutureTask.run(FutureTask.java:242)
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime:     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime:     at java.lang.Thread.run(Thread.java:818)
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime:  Caused by: android.database.sqlite.SQLiteException: near "categories": syntax error (code 1): , while compiling: CREATE TABLE CATEGORIES categories (_id INTEGER PRIMARY KEY AUTOINCREMENT, category_name TEXT, category_date TEXT, frequency TEXT, currency TEXT,duration_value TEXT, duration_modifier TEXT, overage TEXT, surplus TEXT);
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime:     at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime:     at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime:     at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime:     at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime:     at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime:     at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime:     at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1674)
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime:     at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1605)
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime:     at com.example.michael.budgetapp.Database.CategoriesTable.onCreate(CategoriesTable.java:44)
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime:     at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:251)
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime:     at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime:     at com.example.michael.budgetapp.Database.Add.doInBackground(Add.java:37)
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime:     at com.example.michael.budgetapp.Database.Add.doInBackground(Add.java:9)
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime:     at android.os.AsyncTask$2.call(AsyncTask.java:292)
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime:     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
11-17 13:55:55.557 6903-6966/com.example.michael.budgetapp E/AndroidRuntime:     at java.lang.Thread.run(Thread.java:818) 

AddCategory.class:

public class AddCategory extends AppCompatActivity {

EditText catName;
Spinner currencySpinner, freqSpinner, durationValueSpinner, durationModifierSpinner;
LinearLayout overageReaction, surplusReaction;
RadioGroup overageRG, surplusRG;
RadioButton overStatic, overVariable, underStatic, underVariable;
TextView reminder, example;
RelativeLayout categoryRelativeLayout;
Snackbar snackbar;
Time today = new Time(Time.getCurrentTimezone());
String currencySelection, dMSselection, dVSselection;
private Cursor data = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_add_category);

    categoryRelativeLayout = (RelativeLayout) findViewById(R.id.categoryRelativeLayout);
    overageRG = (RadioGroup) findViewById(R.id.overageRG);
    surplusRG = (RadioGroup) findViewById(R.id.surplusRG);
    overStatic = (RadioButton) findViewById(R.id.overStatic);
    overVariable = (RadioButton) findViewById(R.id.overVariable);
    underStatic = (RadioButton) findViewById(R.id.underStatic);
    underVariable = (RadioButton) findViewById(R.id.underVariable);
    overageReaction = (LinearLayout) findViewById(R.id.overageReaction);
    surplusReaction = (LinearLayout) findViewById(R.id.surplusReaction);
    catName = (EditText) findViewById(R.id.catName);
    currencySpinner = (Spinner) findViewById(R.id.currencySpinner);
    freqSpinner = (Spinner) findViewById(R.id.freqSpinner);
    durationValueSpinner = (Spinner) findViewById(R.id.durationValueSpinner);
    durationModifierSpinner = (Spinner) findViewById(R.id.durationModifierSpinner);
    reminder = (TextView) findViewById(R.id.reminder);
    example = (TextView) findViewById(R.id.example);
    Toolbar toolbar = (Toolbar) findViewById(R.id.app_bar);

    setSupportActionBar(toolbar);
    getSupportActionBar().setTitle("Add a Category");
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    ArrayAdapter<CharSequence> currencyAdapter = ArrayAdapter.createFromResource(this,
            R.array.currency, android.R.layout.simple_spinner_item);
    currencyAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    currencySpinner.setAdapter(currencyAdapter);

    ArrayAdapter<CharSequence> freqAdapter = ArrayAdapter.createFromResource(this,
            R.array.frequency, android.R.layout.simple_spinner_item);
    freqAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    freqSpinner.setAdapter(freqAdapter);

    ArrayAdapter<CharSequence> durModAdapter = ArrayAdapter.createFromResource(this,
            R.array.duration, android.R.layout.simple_spinner_item);
    durModAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    durationModifierSpinner.setAdapter(durModAdapter);

    ArrayAdapter<CharSequence> durValueAdapter = ArrayAdapter.createFromResource(this,
            R.array.onetothirtyone, android.R.layout.simple_spinner_item);
    durValueAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    durationValueSpinner.setAdapter(durValueAdapter);

    freqSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            if (freqSpinner.getSelectedItem().toString().equals("Daily")) {
                overageReaction.setVisibility(View.INVISIBLE);
                surplusReaction.setVisibility(View.INVISIBLE);
                reminder.setText(getText(R.string.suggestion));
                example.setVisibility(View.INVISIBLE);
            } else {
                overageReaction.setVisibility(View.VISIBLE);
                surplusReaction.setVisibility(View.VISIBLE);
                reminder.setText(getText(R.string.variableBudgetExplainer));
                example.setVisibility(View.VISIBLE);
            }
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {
            overageReaction.setVisibility(View.INVISIBLE);
            surplusReaction.setVisibility(View.INVISIBLE);
        }
    });
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_add_category, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
/*
    String overageValue, surplusValue;
    overageValue = ((RadioButton)this.findViewById(overageRG.getCheckedRadioButtonId())).getText().toString();
    surplusValue = ((RadioButton)this.findViewById(surplusRG.getCheckedRadioButtonId())).getText().toString();
    */
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }
    if (id == R.id.delete) {
        Toast.makeText(getBaseContext(), "Category data lost!", Toast.LENGTH_LONG).show();
        NavUtils.navigateUpFromSameTask(this);
        return true;
    }

    if (id == R.id.save) {
        if (freqSpinner.getSelectedItem().toString().equals("Daily")) {
            if (TextUtils.isEmpty(catName.getText().toString())) {
                snackbar.make(categoryRelativeLayout, "Please enter a Category name", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            } else {
                today.setToNow();
                Add at = new Add(AddCategory.this);
                at.execute(
                        catName.getText().toString(), // category_name edittext
                        today.format("%Y-%m-%d %H:%M:%S"), // date
                        freqSpinner.getSelectedItem().toString(), // frequency spinner
                        currencySpinner.getSelectedItem().toString(), // currency spinner
                        durationValueSpinner.getSelectedItem().toString(), // duration_value spinner
                        durationModifierSpinner.getSelectedItem().toString(), // duration_modifier spinner
                        ((RadioButton)this.findViewById(overageRG.getCheckedRadioButtonId())).getText().toString(), // overage radiogroup
                        ((RadioButton)this.findViewById(surplusRG.getCheckedRadioButtonId())).getText().toString()  // surplus radiogroup
                );
                Toast.makeText(getBaseContext(), "Category saved!", Toast.LENGTH_LONG).show();
                NavUtils.navigateUpFromSameTask(this);
            }
        } else {
            if (overageRG.getCheckedRadioButtonId() == -1 || surplusRG.getCheckedRadioButtonId() == -1) {
                snackbar.make(categoryRelativeLayout, "Please select your reactions", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            } else if (TextUtils.isEmpty(catName.getText().toString())) {
                snackbar.make(categoryRelativeLayout, "Please enter a Category name", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            } else {
                today.setToNow();
                Add at = new Add(AddCategory.this);
                at.execute(
                        catName.getText().toString(), // category_name spinner
                        today.format("%Y-%m-%d %H:%M:%S"), // date
                        freqSpinner.getSelectedItem().toString(), // frequency spinner
                        currencySpinner.getSelectedItem().toString(), // currency spinner
                        durationValueSpinner.getSelectedItem().toString(), // duration_value spinner
                        durationModifierSpinner.getSelectedItem().toString(), // duration_modifier spinner
                        ((RadioButton)this.findViewById(overageRG.getCheckedRadioButtonId())).getText().toString(), // overage radiogroup
                        ((RadioButton)this.findViewById(surplusRG.getCheckedRadioButtonId())).getText().toString()  // surplus radiogroup
                );
                Toast.makeText(getBaseContext(), "Category saved!", Toast.LENGTH_LONG).show();
                NavUtils.navigateUpFromSameTask(this);
            }
        }
        return true;
    }

    return super.onOptionsItemSelected(item);
}
}

Add.class:

public class Add extends AsyncTask<String, Void, Long> {

private WeakReference<Context> weakReference;
private CategoriesTable db;
private Load load;

public Add(Context context){
    weakReference = new WeakReference<>(context);
    db = CategoriesTable.getInstance(weakReference.get());
}

@Override
protected void onPostExecute(Long newKeyId) {
    load = new Load(weakReference.get());
    load.execute();
}

@Override
protected Long doInBackground(String... params) {
    ContentValues cv = new ContentValues();
    cv.put(CategoriesTable.CATEGORY_NAME, params[0]);
    cv.put(CategoriesTable.DATE, params[1]);
    cv.put(CategoriesTable.FREQUENCY, params[2]);
    cv.put(CategoriesTable.CURRENCY, params[3]);
    cv.put(CategoriesTable.DURATION_VALUE, params[4]);
    cv.put(CategoriesTable.DURATION_MODIFIER, params[5]);
    cv.put(CategoriesTable.OVERAGE, params[6]);
    cv.put(CategoriesTable.SURPLUS, params[7]);
    return db.getWritableDatabase().insert(CategoriesTable.CATEGORIES, null, cv);
}
}

CategoriesTable.class:

public class CategoriesTable extends SQLiteOpenHelper {

private static final String DATABASE_NAME = "budgets.db";
private static final int SCHEMA = 1;
public static final String KEY_ID = "_id";

public static final String CATEGORIES = "categories";

public static final String CATEGORY_NAME = "category_name";
public static final String DATE = "category_date";
public static final String FREQUENCY = "frequency";
public static final String CURRENCY = "currency";
public static final String DURATION_VALUE = "duration_value";
public static final String DURATION_MODIFIER = "duration_modifier";
public static final String OVERAGE = "overage";
public static final String SURPLUS = "surplus";

private static CategoriesTable mInstance = null;

public static synchronized CategoriesTable getInstance(Context context) {
    if (mInstance == null) {
        mInstance = new CategoriesTable(context.getApplicationContext());
    }
    return mInstance;
}

public CategoriesTable(Context context) {
    super(context, DATABASE_NAME, null, SCHEMA);
}

public CategoriesTable(Context context, String name, SQLiteDatabase.CursorFactory factory,
                       int version) {
    super(context, name, factory, version);
}

@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL("CREATE TABLE CATEGORIES categories (_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
            "category_name TEXT, category_date TEXT, frequency TEXT, currency TEXT," +
            "duration_value TEXT, duration_modifier TEXT, overage TEXT, surplus TEXT);");
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    int upgradeTo = oldVersion + 1;
    while (upgradeTo <= newVersion) {
        switch (upgradeTo) {
            case 2:
                break;
        }
        upgradeTo++;
    }
}
}

2 个答案:

答案 0 :(得分:4)

您的创建表声明

中有一个重复的表名

这个:

  db.execSQL("CREATE TABLE categories (_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
        "category_name TEXT, category_date TEXT, frequency TEXT, currency TEXT," +
        "duration_value TEXT, duration_modifier TEXT, overage TEXT, surplus TEXT);");

应为:

$validator = Validator::make(...);

$validator->after(function($validator) use ($email) {
    if (emailExist($email)) {
        $validator->errors()->add('email', 'This email has been used!');
    }
});

if ($validator->fails()) {
    return redirect('somewhere')
        ->withErrors($validator);
}

答案 1 :(得分:2)

您不需要在此处将表格名称放两次

CREATE TABLE CATEGORIES categories

将其更改为

CREATE TABLE categories