【问题标题】:SQLite if input exists in the database skip or overwrite the existing如果数据库中存在输入,则 SQLite 跳过或覆盖现有的
【发布时间】:2019-04-26 16:10:43
【问题描述】:

我有一个作业问题。我在我的 android 应用程序中有一个带有 sqlite 的数据库,并且位置更新来并写入 sql db,但是即将到来的更新有一些相同的数据。我想检查我的数据库中是否有相同的位置,系统跳过或覆盖数据库中现有的位置信息为 x,y 我有一些代码我在下面发布但我的代码总是添加或总是覆盖如果我将其更改为更新替换或类似的东西我的数据库中也有 id。

如何更改和组织我的工作代码?

public void DBCreate(){
    SQLITEDATABASE = openOrCreateDatabase("LatLongDatabase3", Context.MODE_PRIVATE, null);
    SQLITEDATABASE.execSQL("CREATE TABLE IF NOT EXISTS myTable74(id INTEGER PRIMARY KEY AUTOINCREMENT, FAVCurrentLocationLAT VARCHAR,FAVCurrentLocationLONG VARCHAR);");
}

public void SubmitData2SQLiteDB(){
    SQLiteQuery = "INSERT OR REPLACE INTO myTable74(id, FAVCurrentLocationLAT, FAVCurrentLocationLONG) VALUES(NULL,'"+mCurrentLocation.getLatitude()+"','"+mCurrentLocation.getLongitude()+"');";
    SQLITEDATABASE.execSQL(SQLiteQuery);
    Toast.makeText(CampaignActivity.this,"OK", Toast.LENGTH_LONG).show();
}

【问题讨论】:

    标签: java android sql sqlite


    【解决方案1】:

    您不应该使用 INSERT OR REPLACE
    INSERT OR REPLACE 或简单的 REPLACE 所做的是:
    在插入新行之前检查该行是否违反约束并且
    -如果确实违反了约束,则删除现有行,然后插入新行
    -如果不违反约束,则继续插入新行
    在您的表中,唯一存在的约束是:

    id INTEGER PRIMARY KEY
    

    没有别的。
    这意味着无论何时您尝试插入新行:
    - 如果新的id已经存在在表中,那么这个现有的行将被删除并插入新的行
    - 如果新的id尚不存在,则将插入新行。

    这是你想要的吗?
    我认为您想要的是对两列 (FAVCurrentLocationLAT,FAVCurrentLocationLONG) 的唯一性的约束,这应该是表中的 PRIMARY KEY,因为我认为不需要 id(或者可能需要它,但它是不是插入失败的原因)。
    所以把表的CREATE语句改成这样:

    CREATE TABLE myTable74 (
      FAVCurrentLocationLAT TEXT, 
      FAVCurrentLocationLONG TEXT, 
      PRIMARY KEY(FAVCurrentLocationLAT,FAVCurrentLocationLONG)
    );
    

    现在每次执行语句:

    SQLiteQuery = 
      "INSERT OR REPLACE INTO myTable74(FAVCurrentLocationLAT, FAVCurrentLocationLONG) " +
      "VALUES('"+mCurrentLocation.getLatitude()+"','"+mCurrentLocation.getLongitude()+"');";
    

    将插入新的值对并替换现有的值。
    当然不需要替换,因此您可以通过代码检查表中是否已经存在这些值,如果它们确实存在,则根本不执行INSERT(而不是REPLACE)语句。

    【讨论】:

    • 我在语句中有 TEXT 的原因是因为你的代码有VARCHAR。如果值包含小数位,您可以将其替换为 INTEGERREAL
    • 然后使用REAL
    • 实际上,对于 SQLite,一切都是 TEXT。因此,您可以将任何内容存储在定义为 TEXT 或 INTEGER 的列中。所以你可以使用TEXT。数据类型 VARCHAR 不是 SQLite 特定的。它将被视为 TEXT。
    • 在 CREATE 语句中不要使用 REAL,这是用于数字的。使用文本。并在INSERT 语句中删除所有REAL。同时删除您发布的问题/答案。
    • INSERT OR REPLACE INTO myTable2(FAVCampaignName, FAVCampaigncampaignStartDate, FAVCampaigncampaignEndDate)" + " VALUES('"+FSname+"','"+FScampaignStartDate+"','"+FScampaignEndDate+"');
    【解决方案2】:
    INSERT INTO myTable74(id, FAVCurrentLocationLAT, FAVCurrentLocationLONG) 
    VALUES(NULL,'"+mCurrentLocation.getLatitude()+"','"+mCurrentLocation.getLongitude()+"')
    WHERE NOT EXISTS(SELECT id FROM myTable74 WHERE id = your_id);
    

    但是Insert or ReplaceIF not exists 不能一起使用,你不能替换不存在的东西。所以上面只是Insert

    当然,您可以更改id,通过哪一列来检查它是否存在

    【讨论】:

    • 谢谢先生,我要写什么到“your_id”,我可以复制代码并使用它吗?这样代码会自动完成每次更新的工作
    • 将其替换为您的id。是否要通过 id 或纬度或经度检查 db 中的项目是否存在?
    • 先生,我不明白如何更改 ID。如果 lat 或 long 存在,它可以改变 lat long 变量。
    • 我的意思是在(SELECT id FROM myTable74 WHERE id = your_id) 查询中你可以更改id 你想要的任何列,your_id 只是一个占位符,在那里输入实际值
    【解决方案3】:

    Replace 的问题在于,如果记录存在,它将删除该记录及其主键值,然后插入具有新主键值的新记录。如果您有其他表引用了可能是问题的旧主键值。您真正想要做的是检查特定纬度/经度的值是否已经在数据库中,如果是,请不要理会它们(不要删除然后重新插入)。但如果没有,那就做一个简单的插入。所以,在前一篇文章的带领下,我将它稍微修改一下:

    // Don't include ID in the INSERT as primary key should be auto-incrementing field
    INSERT INTO myTable74(FAVCurrentLocationLAT, FAVCurrentLocationLONG) VALUES(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude())
    WHERE NOT EXISTS(SELECT id FROM myTable74 WHERE FAVCurrentLocationLAT = mCurrentLocation.getLatitude() AND FAVCurrentLocationLONG= mCurrentLocation.getLongitude());
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-23
      • 1970-01-01
      • 2014-07-17
      • 1970-01-01
      • 1970-01-01
      • 2012-08-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多