如何从表中检索我的最后一个插入行?
Posted
技术标签:
【中文标题】如何从表中检索我的最后一个插入行?【英文标题】:how I can retrieve my last insert row from table? 【发布时间】:2021-10-07 22:27:45 【问题描述】:我正在创建一个 bmi 应用程序。这是非常简单的应用程序,用户必须输入姓名、体重和身高。然后,它将插入数据库名称 bmi。用户单击按钮计算后,它将根据用户输入的名称计算 bmi。自从我上次尝试以来我如何检索它是他们从数据库中读取第一行。如何检索最后一行?
代码如下:
DataHelper.java
public class DataHelper extends SQLiteOpenHelper
//Database name
private static final String DATABASE_NAME = "assignment.db";
//Database version
private static final int DATABASE_VERSION = 1;
//Create constructor for Data Helper
public DataHelper(Context context)
super(context, DATABASE_NAME, null, DATABASE_VERSION);
@Override
public void onCreate(SQLiteDatabase db)
String sql = "create table bmi(name text primary key, weight double null, height double null);";
Log.d("Data", "onCreate: " + sql);
db.execSQL(sql);
//create method to upgrade database version if database exist
@Override
public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2)
CalculateActivity.java
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calculate);
dbHelper = new DataHelper(this);
text1 = (EditText) findViewById(R.id.name);
text2 = (EditText)findViewById(R.id.height);
text3 = (EditText)findViewById(R.id.weight);
ton1 = (Button) findViewById(R.id.btnGo);
ton1.setOnClickListener(arg0 ->
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.execSQL("insert into bmi(name, weight, height) values ('" +
text1.getText().toString() + "','" +
text2.getText().toString() + "','" +
text3.getText().toString() + "')");
Toast.makeText(getApplicationContext(), "Data Successfully added", Toast.LENGTH_SHORT).show();
Intent i = new Intent(CalculateActivity.this, ResultActivity.class);
startActivity(i);
);
ResultActivity.java
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_result);
dbHelper = new DataHelper(this);
text2 = (EditText) findViewById(R.id.height);
text3 = (EditText)findViewById(R.id.weight);
textname = (EditText) findViewById(R.id.name);
textTotal = (TextView) findViewById(R.id.txtBMITotal);
textBMI = (TextView) findViewById(R.id.txtBMI);
textRisk = (TextView)findViewById(R.id.txtRisk);
bye = (Button) findViewById(R.id.btnBye);
SQLiteDatabase db = dbHelper.getReadableDatabase();
cursor = db.rawQuery("SELECT * FROM bmi ORDER BY name DESC LIMIT 1", null);
cursor.moveToFirst();
if (cursor.getCount() > 0)
cursor.moveToPosition(0);
//below i just want to know whether it retrieved or not
textTotal.setText(cursor.getString(0).toString());
textBMI.setText(cursor.getString(1).toString());
textRisk.setText(cursor.getString(2).toString());
【问题讨论】:
如果你插入了它,为什么你必须通过运行查询来阅读它? 我想通过体重和身高计算bmi来显示bmi的总和,这就是为什么我想阅读它,实际上,textTotal,textBMI和textRisk是textview,可以显示当计算体重指数。 goose 的意思是先计算,再插入。你在那里有价值观。为什么插入它,然后再次从数据库中取出?冗余。 无论如何,如果你想找到最后插入的 id,你通常需要一个时间戳列。但在这种情况下,它完全没有必要,因为您已经可以访问数据库之外的数据。 @nerdgirl 你真的需要使用数据库吗?如果您需要即时计算 bmi,那么您不需要存储任何内容。如果您只需要跟踪一个用户的 bmi,那么您可以使用共享首选项,如果您想为不同的名称存储多个 bmi 值,您只需要使用 db,在这种情况下,您可以在存储之前先计算 bmi,就像 g00se 和 YHStan 说的。 【参考方案1】:您所需要做的就是通过 Intent Extra 将 name 传递给 ResultActivity,然后在 ResultActivty 中提取 Intent Extra,然后使用该名称从 bmi 表中提取行。
所以在 CalculateActivity.java
使用:-
ton1.setOnClickListener(arg0 ->
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.execSQL("insert into bmi(name, weight, height) values ('" +
text1.getText().toString() + "','" +
text2.getText().toString() + "','" +
text3.getText().toString() + "')");
Toast.makeText(getApplicationContext(), "Data Successfully added", Toast.LENGTH_SHORT).show();
Intent i = new Intent(CalculateActivity.this, ResultActivity.class);
i.putExtra("name_extra",text1.getText().toString()); //<<<<<<<<<< ADDED
startActivity(i);
);
在 ResultActivity 中:-
SQLiteDatabase db = dbHelper.getReadableDatabase();
cursor = db.rawQuery("SELECT * FROM bmi WHERE name=? ORDER BY name DESC LIMIT 1", new String[]this.getIntent().getStringExtra("name_extra"));
if (cursor.MoveToFirst())
textTotal.setText(cursor.getString(cursor.getColumnIndex("name")));
textBMI.setText(cursor.getString(cursor.getColumnIndex("weight")));
textRisk.setText(cursor.getString(cursor.getColumnIndex("height")));
else
// Do something here to indicate nothing retrieved
注意更改后的查询要根据传递的值进行选择(不需要 ORDER BY 子句,因为名称是主键,因此必须是唯一的)。
如果移动成功,Cursor 的 moveToFirst
方法将返回 true,否则返回 false(例如,没有行)。所以你只需要moveToFirst
不需要检查计数。
使用 Cursor 的 getColumnIndex(the_column_name)
方法比硬编码特定索引偏移更灵活。
无需使用String的toString
方法获取String。
哦,我想我明白了。我需要在存储之前先计算bmi
您不需要存储附加值,因为您可以通过查询实际进行计算,因此无需存储附加值。所以你的查询可能是这样的:-
`SELECT *, (weight/height)/height AS bmi_value FROM bmi WHERE name=?;`
.....
textBMI.setText(cursor.getString(cursor.getColumnIndex("bmi_value")));
生成的游标将包含表中的所有列(*
)以及列名为 bmi_value 的附加派生(计算)列(由于 AS
子句)。
这假定 BMI 将通过名为 textBMI
的 TextView 对象显示
请注意,也许更正确的查询应该是:-
SELECT *, (coalesce(weight,1.0)/coalesce(height,1.0))/coalesce(height,1.0) AS bmi_value FROM bmi; WHERE name=?;
coalesce 函数从参数/参数列表中返回第一个 NON NULL 值,因此如果 weight 或 height 为 NULL,则使用 1.0。
注意以上为原理代码,尚未编译或运行,可能存在一些错误。
附加
重新计算
如果在 if(moveToFirst())... 中的查询下,我想计算 bmi 并在某个条件下显示?
再次,您可以让 Query 使用 CASE WHEN THEN ELSE END
构造来完成工作,例如:-
SELECT *, (coalesce(weight,1.0)/coalesce(height,1.0))/coalesce(height,1.0) AS bmi_value, CASE WHEN (coalesce(weight,1.0)/coalesce(height,1.0))/coalesce(height,1.0) <= 20 THEN 'good' ELSE 'Malnutrition risk' END AS bmi_state FROM bmi WHERE name=?
因此,光标将包含另一个名为 bmi_state 的列,该列将是 good (bmi 营养不良风险
Double.parseDouble(cursor.getString(cursor.getColumnIndex("weight")))
无需提取字符串然后解析为双精度。 Cursor 具有提取各种类型的方法,因此您可以使用:-
cursor.getDouble(cursor.getColumnIndex("weight"))
查看Cursor 并获得所有信息????方法。
提示
当谈到 SQL for SQLite 时,有各种工具(我使用 Navicat for SQLite,但还有其他工具,例如 DB Browser for SQlite、DBeaver、SQlite Studio)。这些工具非常适合使用 SQL。作为提供上述内容的示例,我使用以下内容来制定/测试上述内容:-
请注意,我已注释掉 WHERE 子句以测试一些场景,包括处理空值。【讨论】:
太棒了,先生。我真的很感激。如果在 if(moveToFirst())... 中的查询下,我想计算 bmi 并在某个条件下显示怎么办?比如,双倍计算 = Double.parseDouble(cursor.getString(cursor.getColumnIndex("weight"))) / (Double.parseDouble(cursor.getString(cursor.getColumnIndex("height"))) * Double.parseDouble(cursor. getString(cursor.getColumnIndex("height")))); if (calculate 我不确定我是否可以应用此代码。因为,在我设置(计算> 20.0)**并输入 bmi 结果大于 20.0 的值后,它无法读取它。所以,我假设在我完成之后,计算结果为 0,因为值为 0? 非常感谢您的帮助,先生,非常感谢以上是关于如何从表中检索我的最后一个插入行?的主要内容,如果未能解决你的问题,请参考以下文章