在 Sqlite (SQLX) 中多次插入时避免插入冲突的惯用方法

问题描述 投票:0回答:1

我有 2 个表格,其中 PK 和 FK 参考如下。

CREATE TABLE IF NOT EXISTS User
(
    userid VARCHAR(255) PRIMARY KEY
);


CREATE TABLE IF NOT EXISTS UserType
(
    email       VARCHAR(255) PRIMARY KEY,
    userId      VARCHAR(255),
    type        VARCHAR(255),
    FOREIGN KEY (userId) REFERENCES User (userId)
);

表:用户

用户ID(PK)
1
2

表:用户类型

电子邮件(PK) 用户 ID (FK) 类型
[电子邮件受保护] 1 xxx
[电子邮件受保护] 2 yyy

我从代码生成用户 ID 并使用 sqlx - sqlite 插入,如下所示

async fn create_user(
        &self,
        user: &User,
    ) -> Result<(), CreateError> {
        let query = "insert into User (id) values (?1)";
        let query_local = "insert or ignore into UserType (email,user_id) values (?1,?2)";
        let mut conn = self
            .pool
            .acquire()
            .map_err("xxx")
            .await?;

        let mut tx = conn.begin().map_err("xxx").await?;

        sqlx::query(query)
            .bind(user.userid.as_str())
            .execute(&mut *tx)
            .map_err("xxx")
            .await?;
        sqlx::query(query_local)
            .bind(user.email.as_str())
            .bind(user.userid.as_str())
            .execute(&mut *tx)
            .map_err("xxx")
            .await?;
        tx.commit().map_err("xxx").await?;
        Ok(())
    }

现在,如果收到重复的电子邮件,在插入“UserType”(第二个)表时发生冲突,如何避免将 UserId 插入“User”(第一个)表中?我是关系数据库和 SQL 的新手。是否有惯用的方法通过查询或事务来做到这一点?请帮忙

注意:我知道这个设计很模糊,但出于应用原因需要进一步处理

sqlite rust sqlx rust-sqlx
1个回答
0
投票

您需要使用

ON CONFLICT {DO SOMETHING}
更新查询。这取决于你在冲突中的作用。 https://www.sqlite.org/lang_conflict.html

© www.soinside.com 2019 - 2024. All rights reserved.