这是我的声明:
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,那么我想更新记录。如果不存在,我要插入记录。
答案 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。