1

我不知道如何查询 SQLite。需要: 1)如果条件(新旧字段条目的比较)替换记录(主键) 2)如果主键上的数据库中不存在这样的条目,则插入一个条目。

重要的是,它必须工作得非常快!我无法提出有效的调查。

编辑。

MyInsertRequest - 所需的表达式。

脚本:

CREATE TABLE testtable (a INT PRIMARY KEY, b INT, c INT)

INSERT INTO testtable VALUES (1, 2, 3)

select * from testtable
1|2|3

-- Adds an entry, because the primary key is not
++ MyInsertRequest VALUES (2, 2, 3) {if c>4 then replace}

select * from testtable
1|2|3
2|2|3

-- Adds
++ MyInsertRequest VALUES (3, 8, 3) {if c>4 then replace}

select * from testtable
1|2|3
2|2|3
3|8|3

-- Does nothing, because such a record (from primary key field 'a') 
-- is in the database and none c>4
++ MyInsertRequest VALUES (1, 2, 3) {if c>4 then replace}

select * from testtable
1|2|3
2|2|3
3|8|3

-- Does nothing
++ MyInsertRequest VALUES (3, 34, 3) {if c>4 then replace}

select * from testtable
1|2|3
2|2|3
3|8|3

-- replace, because such a record (from primary key field 'a') 
-- is in the database and c>2
++ MyInsertRequest VALUES (3, 34, 1) {if c>2 then replace}

select * from testtable
1|2|3
2|2|3
3|34|1
4

3 回答 3

0

不是插入或替换您需要的吗?例如:

INSERT OR REPLACE INTO table (cola, colb) values (valuea, valueb)

当发生 UNIQUE 约束违规时,REPLACE 算法会在插入或更新当前行之前删除导致约束违规的预先存在的行,并且命令会继续正常执行。

您必须将条件放在表上的唯一约束中。它将自动创建索引以提高检查效率。

例如

-- here the condition is on columnA, columnB
CREATE TABLE sometable (columnPK INT PRIMARY KEY,
    columnA INT,
    columnB INT,
    columnC INT,
    CONSTRAINT constname UNIQUE (columnA, columnB)
)

INSERT INTO sometable VALUES (1, 1, 1, 0);
INSERT INTO sometable VALUES (2, 1, 2, 0);

select * from sometable
1|1|1|0
2|1|2|0

-- insert a line with a new PK, but with existing values for (columnA, columnB)
-- the line with PK 2 will be replaced
INSERT OR REPLACE INTO sometable VALUES  (12, 1, 2, 6)

select * from sometable
1|1|1|0
12|1|2|6
于 2013-08-29T08:24:10.553 回答
0

Assuming your requirements are:

  • Insert a new row when a doesn't exists;
  • Replacing row when a exist and existing c greater then new c;
  • Do nothing when a exist and existing c lesser or equal then new c;

INSERT OR REPLACE fits first two requirements.

For last requirement, the only way I know to make an INSERT ineffective is supplying a empty rowset.

A SQLite command like following whould make the job:

INSERT OR REPLACE INTO sometable SELECT newdata.* FROM
    (SELECT 3 AS a, 2 AS b, 1 AS c) AS newdata
    LEFT JOIN sometable ON newdata.a=sometable.a
    WHERE newdata.c<sometable.c OR sometable.a IS NULL;

New data (3,2,1 in this example) is LEFT JOINen with current table data.

Then WHERE will "de-select" the row when new c is not less then existing c, keeping it when row is new, ie, sometable.* IS NULL.

于 2013-08-29T11:11:08.730 回答
0

我尝试了其他答案,因为我也遇到了这个问题的解决方案。

这应该可行,但是我不确定性能影响。我相信您可能需要第一列作为主键是唯一的,否则它每次都会简单地插入一条新记录。

INSERT OR REPLACE INTO sometable
    SELECT columnA, columnB, columnC FROM (
    SELECT columnA, columnB, columnC, 1 AS tmp FROM sometable
        WHERE sometable.columnA = 1 AND
              sometable.columnB > 9
    UNION
        SELECT 1 AS columnA, 1 As columnB, 404 as columnC, 0 AS tmp)
    ORDER BY tmp DESC
    LIMIT 1

在这种情况下,将执行一个虚拟查询并将其联合到第二个查询上,这将对性能产生影响,具体取决于它的编写方式和表的索引方式。下一个性能问题具有潜在的结果是有序和有限的。但是,我希望第二个查询应该只返回一条记录,因此它不应该对性能造成太大影响。

您也可以省略ORDER BY tmp LIMIT 1它,它适用于我的 sqlite 版本,但它可能会影响性能,因为它最终可能会更新记录两次(写入原始值,然后写入新值,如果适用)。

另一个问题是即使条件表明不应更新表,您最终还是会写入表。

于 2015-07-27T22:22:31.360 回答