我的应用有问题。 我的应用程序的作用是:从几个edittexts中获取一些数据(每行3个,动态创建)并将它们放入数据库中。
我希望数据库做的是:取product name
,quantity
和price
并将它们放在表格中。名称应为UNIQUE
(它将用于为自动完成提供动力,它必须是唯一的,不要在AC列表中有重复项。)数据库中的价格必须是为该产品插入的最后价格(例如,如果Cheese
at插入3 $,在Cheese
之后,数据库中的2.5 $我们将找到2.5 $)。数量必须总结(如果我在数量3中输入Cheese,然后再在数据库中输入数量为4的Cheese)我们会找到7)。
现在,我的问题:让我说我在我的购物清单中输入:
1. Hhhh 4 2.5
2. Dddd 3 1
3. Eeee 2 2
4. Aaaa 5 3.5
在我的数据库中,我会发现:
4. Aaaa 4 2.5
2. Dddd 3 1
3. Eeee 2 2
1. Hhhh 5 3.5
因此,问题是它按字母顺序排列产品名称列,但其他列保持相同的顺序,即我在edittexts中输入的顺序。
我做了一些测试,如果我从产品名称列中删除UNIQUE
,它将按原样输入它,但当然,它会创建重复项,我不需要它。我不明白,怎么了 ?为什么UNIQUE
会触发这个?
这是我的代码:
我创建的表格:
public class SQLiteCountryAssistant extends SQLiteOpenHelper {
private static final String DB_NAME = "usingsqlite.db";
private static final int DB_VERSION_NUMBER = 1;
private static final String DB_TABLE_NAME = "countries";
private static final String DB_COLUMN_1_NAME = "country_name";
private static final String DB_COLUMN_2_NAME = "country_counter";
private static final String DB_COLUMN_3_NAME = "country_price";
private static final String DB_CREATE_SCRIPT = "create table "
+ DB_TABLE_NAME
+ " (_id INTEGER PRIMARY KEY,country_name text unique, country_quantity REAL DEFAULT '0',country_price REAL);) ";
private SQLiteDatabase sqliteDBInstance = null;
public SQLiteCountryAssistant(Context context) {
super(context, DB_NAME, null, DB_VERSION_NUMBER);
}
@Override
public void onCreate(SQLiteDatabase sqliteDBInstance) {
Log.i("onCreate", "Creating the database...");
sqliteDBInstance.execSQL(DB_CREATE_SCRIPT);
}
我的插入方法:
public void insertCountry(String countryName, String countryPrice,
String countryQuantity) {
sqliteDBInstance.execSQL("INSERT OR IGNORE INTO " + DB_TABLE_NAME
+ "(country_name, country_quantity, country_price) VALUES('"
+ countryName + "','0', '" + countryPrice + "')");
sqliteDBInstance.execSQL("UPDATE " + DB_TABLE_NAME
+ " SET country_name='" + countryName
+ "', country_quantity=country_quantity+'" + countryQuantity
+ "' WHERE country_name='" + countryName + "';");
sqliteDBInstance.execSQL("UPDATE " + DB_TABLE_NAME
+ " SET country_name='" + countryName + "', country_price='"
+ countryPrice + "' WHERE country_name='" + countryName + "';");
}
这就是我调用insert方法的方法:
for (int g = 0; g < allcant.size() - 1; g++) {
if (prod[g] != "0.0") {
sqlliteCountryAssistant.insertCountry(prod[g],pret[g],cant[g]);
}
另外,请原谅我凌乱的代码,我已经开始学习没有编程背景的android一个月前了。我刚拿到社会学学士学位所以是的,我是一个绝对的初学者。如果有办法做的话它比我做得更好,我很确定有,请给我指路,嘿。
谢谢你,祝你有个美好的一天!
编辑:Aaaand整个db类:
public class SQLiteCountryAssistant extends SQLiteOpenHelper {
private static final String DB_NAME = "usingsqlite.db";
private static final int DB_VERSION_NUMBER = 1;
private static final String DB_TABLE_NAME = "countries";
private static final String DB_COLUMN_1_NAME = "country_name";
private static final String DB_COLUMN_2_NAME = "country_counter";
private static final String DB_COLUMN_3_NAME = "country_price";
private static final String DB_CREATE_SCRIPT = "create table "
+ DB_TABLE_NAME
+ " ( id INTEGER PRIMARY KEY AUTOINCREMENT,country_name text unique, country_quantity REAL DEFAULT '0',country_price REAL)";
private SQLiteDatabase sqliteDBInstance = null;
public SQLiteCountryAssistant(Context context) {
super(context, DB_NAME, null, DB_VERSION_NUMBER);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO: Implement onUpgrade
}
@Override
public void onCreate(SQLiteDatabase sqliteDBInstance) {
Log.i("onCreate", "Creating the database...");
sqliteDBInstance.execSQL(DB_CREATE_SCRIPT);
}
public void openDB() throws SQLException {
Log.i("openDB", "Checking sqliteDBInstance...");
if (this.sqliteDBInstance == null) {
Log.i("openDB", "Creating sqliteDBInstance...");
this.sqliteDBInstance = this.getWritableDatabase();
}
}
public void closeDB() {
if (this.sqliteDBInstance != null) {
if (this.sqliteDBInstance.isOpen())
this.sqliteDBInstance.close();
}
}
public void insertCountry(String countryName, String countryPrice,
String countryQuantity) {
ContentValues cv = new ContentValues();
cv.put("country_name", countryName);
cv.put("country_price", countryPrice);
sqliteDBInstance.insertWithOnConflict(DB_TABLE_NAME, null, cv, sqliteDBInstance.CONFLICT_IGNORE);
// Increment the quantity field (there isn't a good way to do this with sql.update() )
sqliteDBInstance.execSQL("UPDATE " + DB_TABLE_NAME + " SET country_quantity=country_quantity+? WHERE country_name=?",
new Object[] { new Long(countryQuantity), countryName });
/*sqliteDBInstance.execSQL("INSERT OR IGNORE INTO " + DB_TABLE_NAME
+ "(country_name) VALUES('" + countryName + "')");
sqliteDBInstance.execSQL("UPDATE " + DB_TABLE_NAME
+ " SET country_quantity=country_quantity+" + countryQuantity
+ " WHERE country_name='" + countryName + "';");
sqliteDBInstance.execSQL("UPDATE " + DB_TABLE_NAME
+ " SET country_price=" + countryPrice
+ " WHERE country_name='" + countryName + "';");*/
}
public boolean removeCountry(String countryName) {
int result = this.sqliteDBInstance.delete(DB_TABLE_NAME,
"country_name='" + countryName + "'", null);
if (result > 0)
return true;
else
return false;
}
public long updateCountry(String oldCountryName, String newCountryName) {
ContentValues contentValues = new ContentValues();
contentValues.put(DB_COLUMN_1_NAME, newCountryName);
return this.sqliteDBInstance.update(DB_TABLE_NAME, contentValues,
"country_name='" + oldCountryName + "'", null);
}
public String[] getAllCountries() {
Cursor cursor = this.sqliteDBInstance.query(DB_TABLE_NAME,
new String[] { DB_COLUMN_1_NAME }, null, null, null, null,
DB_COLUMN_1_NAME + " ASC");
if (cursor.getCount() > 0) {
String[] str = new String[cursor.getCount()];
// String[] strpri = new String[cursor.getCount()];
int i = 0;
while (cursor.moveToNext()) {
str[i] = cursor.getString(cursor
.getColumnIndex(DB_COLUMN_1_NAME));
// strpri[i] = cursor.getString(cursor
// .getColumnIndex(DB_COLUMN_2_NAME));
i++;
}
return str;
} else {
return new String[] {};
}
}
}
答案 0 :(得分:2)
我还没有想出疯狂的订单,但我发现了两件甚至可能清楚的事情:
一般方法是创建一个insertOrUpdate方法,该方法在数据库中查询条目(在您的情况下为countryName)。如果存在条目,则将更新它,否则将被插入。由于你是一个初学者,这可能是一个很好的任务,你自己应该做到这一点,你应该在不同的问题上得到基本的代码。
最后一个提示(您可能已经看过):使用参数版本和/或数据库中的实际更新/插入方法。
db.insert(TABLE_NAME, null, contentValues); // see class ContentValues for details
根据execSQL()方法,您不应该将它用于任何SELECT / INSERT / UPDATE / DELETE语句:
执行一个非SELECT / INSERT / UPDATE / DELETE的SQL语句。
现在我的问题哪个答案可以帮助我帮助你:
我还想知道您如何验证数据库内容的顺序?您是否在Android代码中创建了查询内容的查询,或者是否使用SQLite管理器工具打开了db文件?如果您查询,您是否也可以在问题中包含查询/显示代码?
答案 1 :(得分:2)
@ WarrenFaith的优秀建议可以补充几件事。我同意错误可能在您未显示的代码中。
quantity=quantity+42
,而不是quantity=quantity+'42'
?
)来避免包括对您的应用程序的SQL插入攻击等问题。你想要这样的东西:
// Insert or ignore.
ContentValues cv = new ContentValues();
cv.put("country_name", country_name);
cv.put("country_price", country_price);
sql.insertWithOnConflict(DB_TABLE_NAME, null, cv, CONFLICT_IGNORE);
// Increment the quantity field (there isn't a good way to do this with sql.update() )
sql.execSQL("UPDATE " + DB_TABLE_NAME + " SET country_quantity=country_quantity+? WHERE country_name=?",
new Object[] { new Long(country_quantity), country_name });
你没有提到LogCat是否干净。它必须至少显示数据库错误的报价问题。还建议您确保删除表并在调试运行之间重建。