英文:
SQL table refusing to insert user input to columns
问题
我正在制作一个应用程序,在该应用程序中,我输入一个名称和一个数字,然后单击保存按钮,将名称保存在名为infinitecounter.db的SQLITE数据库的COUNTER_NAME列下。之后,它将数字保存在CURRENT_CLICKS列中。然而,当我启动我的应用程序并单击保存按钮时,应用程序崩溃。
然后,我从文件中导出了数据库并使用SQLite浏览器打开它,这是我看到的:
SQLITE浏览器
以下是我的数据库代码:
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase;
import android.widget.Toast;
import androidx.annotation.Nullable;
class database1 extends SQLiteOpenHelper {
private Context context;
private static final String DATABASE_NAME = "infinitecounter.db";
private static final int DATABASE_VERSION = 1;
private static final String TABLE_NAME = "infinitecounter list";
private static final String COLUMN_ID = "id";
private static final String COUNTER_NAME = "title";
private static final String CURRENT_CLICKS = "Current Clicks"; // fix later
public database1(@Nullable Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.context = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
String query =
"CREATE TABLE " + TABLE_NAME +
"(" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COUNTER_NAME + " TEXT, " +
CURRENT_CLICKS + " INTEGER);";
db.execSQL(query);
}
@Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
void addinfincounter(String title, int current_clicks) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(COUNTER_NAME, title);
cv.put(CURRENT_CLICKS, current_clicks);
long results = db.insert(TABLE_NAME, null, cv);
if (results == -1) {
Toast.makeText(context, "FAILED!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "SUCCESS!", Toast.LENGTH_SHORT).show();
}
}
}
以下是调用addinfincounter方法的Java页面:
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase;
public class infincounter_setup extends AppCompatActivity {
EditText name, clicks;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_infincounter_setup);
}
public void cancel(View V) {
Intent i = new Intent(this, MainActivity.class);
startActivity(i);
}
public void save(View B) {
name = findViewById(R.id.infincounter_name);
clicks = findViewById(R.id.clicks);
if (name.length() == 0 || name == null) {
Toast.makeText(this, "PLEASE ASSIGN A NAME", Toast.LENGTH_LONG).show();
} else {
database1 myDB = new database1(infincounter_setup.this);
myDB.addinfincounter(name.getText().toString(), Integer.parseInt(clicks.getText().toString()));
}
}
}
英文:
I am making an app where I input a name and a number, and upon clicking SAVE, the name is saved in an SQLITE database named infinitecounter.db under the COUNTER_NAME column. After that, it saves the number in the CURRENT_CLICKS column. However, when I launch my app, and upon clicking the save button. the app crashes.
I then exported the database from the files and opened it using SQLite browser and this is what I saw:
SQLITE browser
Here is my DATABASE code:
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase;
import android.widget.Toast;
import androidx.annotation.Nullable;
class database1 extends SQLiteOpenHelper {
private Context context;
private static final String DATABASE_NAME= "infinitecounter.db";
private static final int DATABASE_VERSION= 1;
private static final String TABLE_NAME = "infinitecounter list";
private static final String COLUMN_ID = "id";
private static final String COUNTER_NAME = "title";
private static final String CURRENT_CLICKS = ("Current Clicks"); // fix later
public database1(@Nullable Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.context = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
String query =
"CREATE TABLE " + TABLE_NAME +
"(" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COUNTER_NAME + " TEXT, " +
CURRENT_CLICKS + " INTEGER);";
db.execSQL(query);
}
@Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
void addinfincounter(String title, int current_clicks){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(COUNTER_NAME, title);
cv.put(CURRENT_CLICKS, current_clicks);
long results = db.insert(TABLE_NAME, null, cv);
if(results == -1){
Toast.makeText(context, "FAILED!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "SUCCESS!", Toast.LENGTH_SHORT).show();
}
}
}
Here is the java page where I activate the addinfincounter method
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase;
public class infincounter_setup extends AppCompatActivity {
EditText name, clicks;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_infincounter_setup);
}
public void cancel(View V){
Intent i = new Intent(this, MainActivity.class);
startActivity(i);
}
public void save(View B) {
name = findViewById(R.id.infincounter_name);
clicks = findViewById(R.id.clicks);
if (name.length() == 0 || name == null) {
Toast.makeText(this, "PLEASE ASSIGN A NAME", Toast.LENGTH_LONG).show();
} else{
database1 myDB = new database1(infincounter_setup.this);
myDB.addinfincounter(name.getText().toString(), Integer.parseInt(clicks.getText().toString()));
}
}
}
答案1
得分: 1
这是问题所在:
private static final String TABLE_NAME = "infinitecounter list";
表名只能包含字母数字字符和'_',或者您可以在名称周围加括号。
参考此答案:https://stackoverflow.com/questions/3694276/what-are-valid-table-names-in-sqlite
英文:
I think this is the problem:
private static final String TABLE_NAME = "infinitecounter list";
The table name can only contain alphanumeric characters and '_' or you can put brackets around the name.
See this answer: https://stackoverflow.com/questions/3694276/what-are-valid-table-names-in-sqlite
答案2
得分: 1
发生的情况是在首次访问数据库(打开)时,也就是尝试插入行时。
-
如果数据库不存在,则创建数据库,并添加android_metadata表(其中包含区域设置)。
-
调用覆盖的onCreate方法,但由于语法错误而失败,如下所示:
android.database.sqlite.SQLiteException: near "list": syntax error (code 1 SQLITE_ERROR): , while compiling: CREATE TABLE infinitecounter list(id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, Current Clicks INTEGER);
-
数据库在应用程序崩溃时关闭。
因此,您只能看到一个单一的表。
根据消息,问题是infinitecounter和list之间有一个空格。SQLite期望要么:
- 一个**
(
**来开始列定义,或者 - 一个**
.
**来指定模式名称和表名称之间的分隔,或者 AS
,如果从SELECT创建和填充表
修复问题的方法是定义表名,使其不会导致语法错误,也许是infinitecounter_list(如下所示)。
- 如果将名称括起来,就像是关键字一样,那么在表名中可以有空格,如https://www.sqlite.org/lang_keywords.html中所示 [infinitecounter list]。
更改名称后,由于onCreate方法仅在创建数据库时运行一次,您应该卸载应用程序并重新运行(卸载会删除数据库)。
注意,您可能会遇到current clicks列名的类似问题。
根据上述方法,使用:
private static final String TABLE_NAME = "infinitecounter_list"; // <<<<<<<< CHANGED
private static final String COLUMN_ID = "id";
private static final String COUNTER_NAME = "title";
private static final String CURRENT_CLICKS = ("Current_Clicks"); // <<<<<<<< CHANGED fix later
然后使用以下代码运行应用程序:
public class MainActivity extends AppCompatActivity {
database1 db;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = new database1(this);
db.addinfincounter("Title1",100);
}
}
然后使用应用程序检查显示:
英文:
What is happening is that when the database is first accessed (opened), which is when you try to insert the row.
-
The database is created, if it does not already exist and the android_metadata table is added (it contains the locale).
-
The overridden onCreate method is called but that fails due to a syntax error as per:-
android.database.sqlite.SQLiteException: near "list": syntax error (code 1 SQLITE_ERROR): , while compiling: CREATE TABLE infinitecounter list(id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, Current Clicks INTEGER);
-
The database is closed as part of the App crashing.
Hence why you just see that single table.
The issues, as per the message, is that there is a space between infinitecounter and list. SQLite would be expecting either:-
-
an
(
to start the column definitions, or -
a
.
to specify the separation of the schema name and the table name, or -
AS
if creating and populating the table from a SELECT -
This may well be highlighted in Android Studio e.g.
To fix the issue you need to define the table name so that it does not result in the syntax error, perhaps infinitecounter_list (as used below).
- You could have the space in the table name if the name were enclosed as if it were keyword as per https://www.sqlite.org/lang_keywords.html e.g. [infinitecounter list].
After changing the name, as the onCreate method only runs once when the database is created, you should uninstall the app and rerun (uninstall results in the database being deleted).
Note you will have a similar issue with the current clicks column name.
Following the above i.e. using:-
private static final String TABLE_NAME = "infinitecounter_list"; //<<<<<<<<<< CHANGED
private static final String COLUMN_ID = "id";
private static final String COUNTER_NAME = "title";
private static final String CURRENT_CLICKS = ("Current_Clicks"); //<<<<<<<<<< CHANGED fix later
And then running the App with:-
public class MainActivity extends AppCompatActivity {
database1 db;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = new database1(this);
db.addinfincounter("Title1",100);
}
}
and then using App Inspection show:-
i.e. The table has been created and a row inserted both as expected.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论