如果记录存在,如何执行更新;如果SQLite中不存在,如何插入?

时间:2018-07-16 12:16:13

标签: sql sqlite

这是我的声明:

CASE
    WHEN
        EXISTS
        (
            SELECT
                1 
            FROM
                Transactions 
            WHERE
                Hash = 'VLEYCBLTDGGLHVQEWWIQ' 
                AND Time = 1531739096
        )
    THEN
        UPDATE
            Transactions 
        SET
            BlockID = 0, PoolHeight = NULL 
        WHERE
            Hash = 'VLEYCBLTDGGLHVQEWWIQ' 
            AND Time = 1531739096 
    ELSE
        INSERT INTO Transactions (Hash, Time, _fROM, Signature, Mode, BlockID, OutputValue, PoolHeight) 
            VALUES('VLEYCBLTDGGLHVQEWWIQ', 1531739096, 'GENESIS', 'GENESIS', - 1, 0, 0, NULL)
END;

错误:

System.Data.SQLite.SQLiteException: 'SQL logic error near "CASE": syntax error'

基本上:如果Exists为true,那么我想更新记录。如果不存在,我要插入记录。

1 个答案:

答案 0 :(得分:3)

您将需要在您的应用程序中执行此操作。 CASE表达式不能用于控制流。为此,许多RDBMS支持IF语句,但SQLite不支持。 SQLite的SQL方言不支持SQL的控制流。

对于此问题,您可以尝试使用SQLite's INSERT OR REPLACE syntax,但查看您的查询似乎并不完全符合您的尝试。您将在发生冲突时更新Signature,Mode,BlockID,OutputValue和PoolHeight,而看起来您只想更新BlockID和PoolHeight。

您也许可以使用INSERT [...] ON CONFLICT UPDATE语句,但是我以前没有使用过所谓的UPSERT clause。我相信它会像这样:

INSERT INTO Transactions (Hash, Time, _fROM, Signature, Mode, BlockID, OutputValue, PoolHeight) 
VALUES('VLEYCBLTDGGLHVQEWWIQ', 1531739096, 'GENESIS', 'GENESIS', - 1, 0, 0, NULL)
ON CONFLICT (Hash, Time) DO UPDATE SET BlockID = 0, PoolHeight = NULL 
    WHERE Hash = 'VLEYCBLTDGGLHVQEWWIQ' AND Time = 1531739096;

但是,我自己从未在SQLite上使用过此语句,因此我不确定它的行为方式。似乎确实需要为CONFLICT指定的列被索引。我并不完全确定WHERE子句在这里甚至是必要的。阅读文档并首先进行广泛的测试。

另一种选择是每次仅运行UPDATE语句,然后if you get zero records affected运行INSERT。