【问题标题】:which sqlite statement can produce a result to indicate duplicate entries? Android哪个 sqlite 语句可以产生指示重复条目的结果?安卓
【发布时间】:2010-12-10 17:20:43
【问题描述】:

对于我的应用程序,我正在尝试在没有重复条目的情况下添加条目,如果有重复项,请通知用户并让他重试。使用SQLite,对我知之甚少,这两种方式我都试过了,想知道哪一种更好,更高效,还是更好的开发方式?

第一种方式:

db.execSQL("INSERT INTO " + DatabaseHelper.DATABASE_TABLE + 
"(LATITUDE, LONGITUDE, RATING) SELECT " + latitude + ", " + longitude + ", " + rating +
" WHERE NOT EXISTS (SELECT 1 FROM " + DatabaseHelper.DATABASE_TABLE +
" WHERE LATITUDE = " + latitude + " AND LONGITUDE = " + longitude + ")");

第二种方式:

    long id = -1;
    try {
        id = db.compileStatement(
                "SELECT COUNT(*) FROM " + DatabaseHelper.DATABASE_TABLE
                        + " WHERE LATITUDE = " + latitude
                        + " AND LONGITUDE = " + longitude)
                .simpleQueryForLong();
    } catch (NullPointerException e) {
        return -1;
    }
    return id;

第一种方法,插入或忽略值,我这样做检查,在调用之前将行的行数存储到一个变量中,调用该函数,然后检查其结果。如果结果不高于调用前的结果,则插入被忽略,提示用户“值存在”消息。 (很草率,我知道,但危急时刻需要采取危急措施)

第二种方式,返回与我要存储的数字匹配的实际行数,如果返回的数字大于1,提示用户“值存在”消息。

我一直在来回尝试不同的方法,但我不知道如何设置 SQLite 以拥有 UNIQUE 对,有人告诉我这将是最简单的。如果有人可以纠正这些方式中的任何一种和/或对它们发表评论,那将不胜感激。

谢谢

【问题讨论】:

    标签: android sqlite insert return-value exists


    【解决方案1】:

    这就是我理解你想要的:拥有一个表 Database_Table(如果我可以这么说,不是最具描述性的名称),它绝不允许为两行输入相同的纬度和经度对。

    如果正确,您希望声明包含纬度和经度列的 PRIMARY 或 UNIQUE KEY。如果您这样做,那么任何插入同一对的尝试都将引发异常,您可以捕获并通知用户。使用这种技术,您将不需要在查询中使用 WHERE NOT EXISTS (...) 子句,只需执行简单的 INSERT 并让 SQLite 提醒您违反 UNIQUEness 约束。

    如果您的表已经存在,则可以使用 SQL 命令CREATE INDEX 最轻松地添加键。由于任何表上可能只有一个 PRIMARY KEY,因此如果表上已有 PRIMARY KEY,则需要为此使用 UNIQUE KEY。

    您将使用的 CREATE INDEX 语句的最简单形式是:

    CREATE UNIQUE INDEX lat_long_unique ON Database_Table(latitude, longitude)
    

    【讨论】:

    • 我的表实际上并没有命名为 Database_Table,它是我的 DatabaseHelper 类中的一个字符串常量,我考虑过创建索引,但我有四个字段,我只希望其中两个是唯一的,我可以通过 CREATE INDEX 执行此操作,然后执行简单的 INSERT OR IGNORE?如果是这种情况,SQLite 将如何报告 UNIQUEness 约束?提前致谢。
    • 我知道如果字段是唯一的,我可以在字段上使用 INSERT OR IGNORE 语句,这是我的情况。我判断该值是被插入还是被忽略的方法是在调用之前存储行数并在之后进行比较,是否有任何 cmets?
    • @Anthony:您创建的索引仅包括您希望唯一的两个字段。您无需计算行数并进行比较。并且不要使用 OR IGNORE,使用 ABORT(默认)或 ROLLBACK,具体取决于您使用事务的方式。使用这种技术,您只对数据库执行一个命令 (INSERT),查看是否生成错误 SQLITE_CONSTRAINT。如果是,您尝试(但失败)插入重复行。
    【解决方案2】:

    在我看来,使用原始纬度/经度并不是检查重复项的好方法。使用 Android 的 GeoPoint 1E6 格式的每个可能的纬度/经度组合覆盖的区域小于 5 平方英寸。当然,这个尺寸会根据你在地球上的位置而有所不同,但它是一个很好的经验法则。所以你至少应该根据你想要测量的东西的大小将你的纬度/经度四舍五入到最接近的十、百或千。

    在将其存储到数据库之前:

    lat = (lat/1000)*1000; 
    lon = (lon/1000)*1000;
    

    这是一个计算地球上纬度/经度点之间距离的好工具:

    http://jan.ucc.nau.edu/~cvm/latlongdist.html

    【讨论】:

      【解决方案3】:

      我决定采用第二种方法(见上文)

      自创建UNIQUE INDEX 以来的原因似乎对我不起作用,并且无论是我的结果还是 SQLite 的结果,这对我来说都是一项艰巨的任务。

      它的目的不是微不足道的,方法可能是基本的,但它可以满足我的需要。

      我希望遇到这种情况的人可以受到这里留下的答案的影响,并希望他们比我有更好的运气。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-12-28
        • 2012-12-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-27
        • 1970-01-01
        相关资源
        最近更新 更多