我在android中第一次使用SQLite并且遇到了这个异常
android.database.sqlite.SQLiteException: no such table: employees (code 1)
。我不知道如何解决这个问题。谁能请帮忙。
MainActivity
public class MainActivity extends AppCompatActivity implements View.OnClickListener, Activity {
public static final String DATABASE_NAME = "myemployeedatabase";
TextView textViewViewEmployees;
EditText editTextName, editTextSalary;
Spinner spinnerDepartment;
SQLiteDatabase mDatabase;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textViewViewEmployees = (TextView) findViewById(R.id.textViewViewEmployees);
editTextName = (EditText) findViewById(R.id.editTextName);
editTextSalary = (EditText) findViewById(R.id.editTextSalary);
spinnerDepartment = (Spinner) findViewById(R.id.spinnerDepartment);
findViewById(R.id.buttonAddEmployee).setOnClickListener(this);
textViewViewEmployees.setOnClickListener(this);
//creating a database
mDatabase = openOrCreateDatabase(DATABASE_NAME, MODE_PRIVATE, null);
}
@Override
public void createEmployeeTable() {
mDatabase.execSQL(
"CREATE TABLE IF NOT EXISTS employees (\n" +
" id int NOT NULL CONSTRAINT employees_pk PRIMARY KEY,\n" +
" name varchar(200) NOT NULL,\n" +
" department varchar(200) NOT NULL,\n" +
" joiningdate datetime NOT NULL,\n" +
" salary double NOT NULL\n" +
");"
);
}
//this method will validate the name and salary
//dept does not need validation as it is a spinner and it cannot be empty
private boolean inputsAreCorrect(String name, String salary) {
if (name.isEmpty()) {
editTextName.setError("Please enter a name");
editTextName.requestFocus();
return false;
}
if (salary.isEmpty() || Integer.parseInt(salary) <= 0) {
editTextSalary.setError("Please enter salary");
editTextSalary.requestFocus();
return false;
}
return true;
}
//In this method we will do the create operation
private void addEmployee() {
String name = editTextName.getText().toString().trim();
String salary = editTextSalary.getText().toString().trim();
String dept = spinnerDepartment.getSelectedItem().toString();
//getting the current time for joining date
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss");
String joiningDate = sdf.format(cal.getTime());
//validating the inptus
if (inputsAreCorrect(name, salary)) {
String insertSQL = "INSERT INTO employees \n" +
"(name, department, joiningdate, salary)\n" +
"VALUES \n" +
"(?, ?, ?, ?);";
//using the same method execsql for inserting values
//this time it has two parameters
//first is the sql string and second is the parameters that is to be binded with the query
mDatabase.execSQL(insertSQL, new String[]{name, dept, joiningDate, salary});
Toast.makeText(this, "Employee Added Successfully", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.buttonAddEmployee:
addEmployee();
break;
case R.id.textViewViewEmployees:
startActivity(new Intent(this, EmployeeActivity.class));
break;
}
}
}
logcat的
android.database.sqlite.SQLiteException: no such table: employees (code 1): , while compiling: INSERT INTO employees
(name, department, joiningdate, salary)
VALUES
(?, ?, ?, ?);
#################################################################
Error Code : 1 (SQLITE_ERROR)
Caused By : SQL(query) error or missing database.
(no such table: employees (code 1): , while compiling: INSERT INTO employees
(name, department, joiningdate, salary)
VALUES
(?, ?, ?, ?);)
DBHelper
public class DBHelper extends SQLiteOpenHelper {
// If you change the database schema, you must increment the database version.
public static final int DATABASE_VERSION = 1;
public static final String DATABASE_NAME = "myemployeedatabase";
public DBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE "+ EmployeesEntity.TABLE_NAME+" ("
+ EmployeesEntity.id+" INTEGER PRIMARY KEY AUTOINCREMENT, "
+ EmployeesEntity.name +" TEXT,"
+ EmployeesEntity.department +" TEXT,"
+ EmployeesEntity.joiningdate +" INTEGER,"
+ EmployeesEntity.salary +" REAL);");
}
private class EmployeesEntity implements BaseColumns {
public static final String TABLE_NAME = "employees ";
public static final String id = "id";
public static final String name = "name";
public static final String department = "department";
public static final String joiningdate = "joiningdate ";
public static final String salary = "salary ";
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// This database is only a cache for online data, so its upgrade policy is
// to simply to discard the data and start over
onCreate(db);
}
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
onUpgrade(db, oldVersion, newVersion);
}
}
答案 0 :(得分:1)
我认为您的问题是您按照mDatabase = openOrCreateDatabase(DATABASE_NAME, MODE_PRIVATE, null);
创建数据库,然后单击TextView
,它会触发调用调用onClickListener
方法的addEmployee
insert
SQLiteDatabase createEmployeeTable()
方法。在此阶段,由于您尚未创建表,因此数据库为空。
您有两个简单的选项可以解决此问题: -
第一种是调用 //creating a database
mDatabase = openOrCreateDatabase(DATABASE_NAME, MODE_PRIVATE, null);
createEmployeeTable(); //<<<< ADDED
,例如添加行
SQLiteDatabase mDatabase;
第二种方法是利用你编写的DBHelper。这样做: -
为DBHelper添加一个类变量(比如DBHelper mDBHlpr;
之后),例如
//creating a database
mDatabase = openOrCreateDatabase(DATABASE_NAME, MODE_PRIVATE, null);
而不是: -
//creating a database
mDBHlpr = new DBHelper(this);
mDatabase = mDBHlpr.getWritableDatabase();
有: -
onCreate
请注意。第二种方法将要求删除数据库(见下文),因为只有在创建数据库时才会调用DBHelper的createEmployeeTable()
方法。
我建议第二个选项更可取(然后可以删除{{1}}方法。)
我还建议删除应用数据或卸载应用(删除现有数据库)
答案 1 :(得分:0)
尝试将compile 'com.facebook.stetho:stetho:1.5.0'
放在您的gradle上,这样您就可以在chrome://inspect
上看到您的数据库(如果已创建)
另外,尝试通过创建新类来创建数据库和表。
public class DBHelper extends SQLiteOpenHelper {
// Database Information
public static final String DB_NAME = "DATABASE_NAME";
// database version
static final int DB_VERSION = 1;
//<editor-fold desc="CREATE_KMPost_TABLE QUERY">
private static final String CREATE_KMPost_TABLE = "CREATE TABLE IF NOT EXISTS " + KM_Post + "("
+ KMPost_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ ROUTE_NAME + " VARCHAR,"
+ PLACE + " VARCHAR,"
+ POST + " INTEGER,"
+ PRICE + " DOUBLE,"
+ DISCOUNTED_PRICE + " DOUBLE,"
+ PRICE2 + " DOUBLE,"
+ DISCOUNTED_PRICE2 + " DOUBLE,"
+ PRICE3 + " DOUBLE,"
+ DISCOUNTED_PRICE3 + " DOUBLE)";
//</editor-fold>
public DBHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_KMPost_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
onCreate(db);
}
答案 2 :(得分:0)
好吧我猜你在创建数据库时遇到的问题
您正在处理SQlite没有MYSQL或SQLSERVER
所以你可以尝试一下
db.execSQL("CREATE TABLE "+ EmployeesEntity.TABLE_NAME+" ("
+ EmployeesEntity.id+" INTEGER PRIMARY KEY AUTOINCREMENT, "
+ EmployeesEntity.name +" TEXT,"
+ EmployeesEntity.department +" TEXT,"
+ EmployeesEntity.joiningdate +" INTEGER,"
+ EmployeesEntity.salary +" REAL);");
并添加此类
private class EmployeesEntity implements BaseColumns {
public static final String TABLE_NAME = "employees ";
public static final String id = "id";
public static final String name = "name";
public static final String department = "department";
public static final String joiningdate = "joiningdate ";
public static final String salary = "salary ";
}
现在您可以轻松地进行查询而无需担心名称
<强>更新强>
你使用datetime作为String ..最好将它用作Long Variable
就像我在SQL strutcre中所做的那样
所以在你的插入查询中不要把DateTime作为字符串你可以在这里获取它
Calendar calendar = Calendar.getInstance();
values.put(Time,calendar.getTimeInMillis());
答案 3 :(得分:0)
使用SQLiteOpenHelper
课来代替您处理工作。它将为您提供所需的必要工作方法。
您可以看到Android培训提供的示例here。
public class FeedReaderDbHelper extends SQLiteOpenHelper {
// If you change the database schema, you must increment the database version.
public static final int DATABASE_VERSION = 1;
public static final String DATABASE_NAME = "FeedReader.db";
public FeedReaderDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public void onCreate(SQLiteDatabase db) {
db.execSQL(SQL_CREATE_ENTRIES);
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// This database is only a cache for online data, so its upgrade policy is
// to simply to discard the data and start over
db.execSQL(SQL_DELETE_ENTRIES);
onCreate(db);
}
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
onUpgrade(db, oldVersion, newVersion);
}
}