如何从表中检索我的最后一个插入行?

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? 非常感谢您的帮助,先生,非常感谢

以上是关于如何从表中检索我的最后一个插入行?的主要内容,如果未能解决你的问题,请参考以下文章

从表中检索最后 N 条记录

如何从表中检索票数最高的候选人姓名[关闭]

如何从表中选择记录并插入另一个表?

如何从表中删除除前两个和最后一个之外的所有行?

TSQL 从表中选择最后 10 行?

Laravel 4 - 从表中获取最后一个 id