微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 Sqlite 3.34 中执行 UPSERT 时出错 - 错误:“DO”附近:语法错误

如何解决在 Sqlite 3.34 中执行 UPSERT 时出错 - 错误:“DO”附近:语法错误

我正在尝试将每日 CSV 加载文件加载到 main 表中,以便插入所有新记录并更新所有现有记录。为此,我正在使用 sqlite 的 UPSERT 功能

这是我的 shell 脚本。


LOAD_FILE="/tmp/main.csv"
LOAD_TABLE="tbl_tmp_main"
MAIN_TABLE="tbl_main"
COLUMNS="t_id,t_col1,t_col2"


CREATE_TABLE_QUERY="DROP TABLE IF EXISTS $LOAD_TABLE; CREATE TABLE $LOAD_TABLE AS SELECT $COLUMNS FROM $MAIN_TABLE WHERE false"
LOAD_TABLE_QUERY=".separator ','\n.import '$LOAD_FILE' $LOAD_TABLE"
UPSERT_TABLE_QUERY="
    INSERT INTO $MAIN_TABLE($COLUMNS) SELECT $COLUMNS FROM $LOAD_TABLE
    ON CONFLICT(t_id) DO UPDATE
    SET
        t_col1 = excluded.t_col1,t_col2 = excluded.t_col2
    ;
"

echo ""
echo "$CREATE_TABLE_QUERY" | sqlite3 mydatabase.sqlite3            # <-- This works
echo "[INFO] Temporary Table Created."

echo "$LOAD_TABLE_QUERY" | sqlite3 mydatabase.sqlite3              # <-- This works
echo "[INFO] Data Loaded into Temporary Table."

echo "$UPSERT_TABLE_QUERY" | sqlite3 mydatabase.sqlite3            # <-- This errors out
echo "[INFO] Records Inserted/Updated."
echo ""

这是错误

Error: near line 2: near "DO": Syntax error

我试图检查 documentation,但我不确定上面的查询有什么问题。有人可以指出为什么它不起作用。

这是我的sqlite版本

-> sqlite3 --version
3.34.1 2021-01-20 14:10:07 10e20c0b43500cfb9bbc0eaa061c57514f715d87238f4d835880cd846b9ebd1f

解决方法

错误是由文档中提到的 Parsing Ambiguity 引起的。您需要添加 WHERE true 作为 SELECT 子句的一部分,这应该会修复它。

这是您更新的 UPSERT 查询。

INSERT INTO $MAIN_TABLE($COLUMNS) SELECT $COLUMNS FROM $LOAD_TABLE  WHERE true
--                                                                  ^^^^^^^^^^
ON CONFLICT(t_id) DO UPDATE
SET
    t_col1 = excluded.t_col1,t_col2 = excluded.t_col2
;

这是 Docs 中的部分。

解析歧义

当 UPSERT 附加到的 INSERT 语句从 SELECT 语句中获取其值时,存在潜在的解析歧义。解析器可能无法判断“ON”关键字是否引入了 UPSERT 或者它是否是连接的 ON 子句。要解决此问题,SELECT 语句应始终包含 WHERE 子句,即使该 WHERE 子句只是“WHERE true”。

ON 的歧义使用:

INSERT INTO t1 SELECT * FROM t2
ON CONFLICT(x) DO UPDATE SET y=excluded.y;

使用 WHERE 子句解决歧义:

INSERT INTO t1 SELECT * FROM t2 WHERE true
ON CONFLICT(x) DO UPDATE SET y=excluded.y;

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?