简体   繁体   English

Android sqlite-仅将新记录添加到表

[英]Android sqlite - adding only new records to table

I am collecting the phone's call log into a table. 我正在将电话的通话记录收集到一个表中。

This works great: 这很好用:

public long populate_Calls(String name, String phone, String type, String duration, String date, String contactid) {
        ContentValues cv = new ContentValues();
             cv.put(KEY_NAME, name);
             cv.put(KEY_PHONE, phone);
             cv.put(KEY_TYPE, type);
             cv.put(KEY_DURATION, duration);
             cv.put(KEY_DATE, date);
             cv.put(KEY_CONTACTID, contactid);

        return ourDatabase.insert(DATABASE_TABLE, null, cv);        
    }

Let's suppose the table consists of 455 records. 假设该表包含455条记录。 Now the user makes some calls, and refreshes the table. 现在,用户拨打了一些电话,并刷新了表格。 I want only the new call data to be added to the table. 我只希望将新的通话数据添加到表中。 I have been trying with this code (I don't really understand it though) but every time I refresh the table, more and more records are added. 我一直在尝试使用此代码(虽然我不太了解),但是每次刷新表时,都会添加越来越多的记录。 In the emulator it works fine (there I only got 12 outgoing calls). 在模拟器中,它工作正常(我只有12个拨出电话)。

I guess I need to watch only the phone number and the date since that identifies the call. 我想我只需要看电话号码和日期,因为那可以识别呼叫。 If a record with that number and at that date already exists, just jump to the next record. 如果具有该编号并在该日期的记录已经存在,只需跳转到下一个记录。 If it does not exist, add it to the table. 如果不存在,请将其添加到表中。 Right? 对?

    public void populate_Calls2(String name, String phone, String type, String duration, String date, String contactid) {
 ourDatabase.execSQL("INSERT INTO " + DATABASE_TABLE + " (" + KEY_NAME + "," + KEY_PHONE + "," + KEY_TYPE + "," + KEY_DURATION + "," + KEY_DATE + "," + KEY_CONTACTID + ") SELECT * FROM (SELECT '" + name  + "'," + phone + "," + type + "," + duration + "," + date + "," + contactid + ") WHERE NOT EXISTS (SELECT * FROM " + DATABASE_TABLE + " WHERE " + KEY_PHONE + " = '" + phone + "' AND " + KEY_DATE + " = '" + date + "') LIMIT 1;");    

    }

I also tried this but I get 我也尝试了这个但是我得到了

Failure 1 (near "SELECT": syntax error) on 0x11a2f0 when preparing 'INSERT INTO CallTable VALUES(name,phone,type,duration,date,contactid) SELECT * FROM CallTable WHERE NOT EXISTS (SELECT * FROM CallTable WHERE phone = '30411552' AND date = '1338569074976') LIMIT 1;'. 在准备'INSERT INTO CallTable VALUES(name,phone,type,duration,date,contactid)时,在0x11a2f0上发生故障1(在“ SELECT”附近:语法错误)SELECT * FROM CallTable根本不存在(SELECT * FROM CallTable WHERE电话='30411552 'AND date ='1338569074976')LIMIT 1;'。

and syntax error: 和语法错误:

ourDatabase.execSQL("INSERT INTO " + DATABASE_TABLE + " VALUES(" + KEY_NAME + "," + KEY_PHONE + "," + KEY_TYPE + "," + KEY_DURATION + "," + KEY_DATE + "," + KEY_CONTACTID + ") SELECT * FROM " + DATABASE_TABLE + " WHERE NOT EXISTS (SELECT * FROM " + DATABASE_TABLE + " WHERE " + KEY_PHONE + " = '" + phone + "' AND " + KEY_DATE + " = '" + date + "') LIMIT 1;");

You do not need to check the database for duplicates if you set it up to do that for you when you create the table. 如果您在创建表时将数据库设置为重复数据库,则无需检查数据库是否重复。

Your table creation string might look like this: 您的表创建字符串可能如下所示:

private static final String CREATE_TABLE = "create table "
        + YOUR_TABLE + " (_id integer primary key autoincrement, "
        + KEY_NAME + " text not null,"
        + KEY_PHONE + " text not null,"
        + KEY_TYPE + " text not null,"
        + KEY_DURATION + " text not null,"
        + KEY_DATE + " text not null,"
        + KEY_CONTACTID + " integer not null,"
        + "UNIQUE(" + KEY_PHONE + "," + KEY_DATE + ") ON CONFLICT IGNORE);";

That sets it up so that if you have a combination of phone and date that are the same the record will cause a constraint violation and the insert/update of that record will be ignored (You can change the last bit to ON CONFLICT FAIL to make it throw an error you can catch rather than silently skipping the insert/update operation). 这样设置后,如果电话和日期的组合相同,则该记录将导致约束冲突,并且该记录的插入/更新将被忽略(您可以将最后一位更改为ON CONFLICT FAIL进行更改会引发您可以捕获的错误,而不是无声地跳过插入/更新操作)。

This will make it work whether you use insert(), update(), or replace(). 无论您使用insert(),update()还是replace(),都可以使用它。

Edit 编辑

The query I proposed does not work, so I removed it! 我提出的查询无效,因此将其删除!

Updated answer 更新的答案

You should do what hm. 你应该做什么。 suggests. 提示。 Create a unique column in you db, which you populate with something like phone+duration+date, and then do 在您的数据库中创建一个唯一的列,用诸如phone + duration + date之类的内容填充,然后执行

"INSERT OR IGNORE INTO " + DATABASE_TABLE + " values(" + THE_VALUES + ");"

When inserting new values, old values will be ignored. 插入新值时,旧值将被忽略。

You can also make a unique field, where you safe a generated code based on the containing date and phone number. 您还可以创建一个唯一字段,在其中您可以根据所包含的日期和电话号码来保护生成的代码。 Since the field is unique, it will not added if the code already exists. 由于该字段是唯一的,因此如果代码已经存在,则不会添加。

you can also try updateOrInsert. 您也可以尝试updateOrInsert。 So first you can try to update the data it will usually return the row id if data exists. 因此,首先您可以尝试更新数据,如果数据存在,通常将返回行ID。 then you can insert the data if no row id was returned from updating. 那么如果更新未返回任何行ID,则可以插入数据。 http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html

Another scenario to why you are seeing data could be because you are not clearing the application data when you are rebuilding the application. 为何看到数据的另一种情况可能是因为在重建应用程序时没有清除应用程序数据。 On your device go to Settings -> Applications -> Manage Applications -> " your application" clear data 在设备上,转到设置->应用程序->管理应用程序->“您的应用程序”清除数据

I guess I need to watch only the phone number and the date since that identifies the call. 我想我只需要看电话号码和日期,因为那可以识别呼叫。 If a record with that number and at that date already exists, just jump to the next record. 如果具有该编号并在该日期的记录已经存在,只需跳转到下一个记录。

To do an 'insert or replace': 要“插入或替换”:

  1. Make a composite primary key for the table with the fields KEY_PHONE and KEY_DATE . 使用字段KEY_PHONEKEY_DATE为表创建一个复合主键。

  2. Use the replace (..) method on the SQLiteDatabase instead of the insert (...) that you are currently using. SQLiteDatabase上使用replace (..)方法,而不要使用当前正在使用的insert (...) So your populate_Calls return statement should look like: 因此,您的populate_Calls返回语句应如下所示:

    return ourDatabase.replace(DATABASE_TABLE, null, cv);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM