获取sqldelight中插入行的行id

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

我正在尝试使用 sqldelight 插入一个项目,但在插入后也返回该项目的 id。在 sqldelight 中似乎没有办法做到这一点。

我可以在插入后调用类似

SELECT last_insert_rowid();
的内容,但这是前进的最佳方式吗?

sqlite sqldelight
2个回答
13
投票

您可以将此命令添加到您的 .sq 文件中:

lastInsertRowId:
SELECT last_insert_rowid()
;

它会返回最后插入行的

id

请参阅 Github 上的这个 issue 了解更多信息。


0
投票

这个问题是 5 年前提出的,但仍然相关))

我的解决方案是,在一次事务中,我们插入数据并立即请求 PRIMARY KEY 字段的最大值。

这是我的例子。

DayliForecast.sq:

import kotlin.Int;

CREATE TABLE IF NOT EXISTS DailyForecast (
    pid             INTEGER PRIMARY KEY AUTOINCREMENT DEFAULT NULL,
    year            INTEGER AS Int  NOT NULL,
    month           INTEGER AS Int  NOT NULL,
    day_of_month    INTEGER AS Int  NOT NULL,
    hours_of_sun    REAL            NOT NULL DEFAULT 0,
    forecast_key    TEXT            NOT NULL
);

CREATE UNIQUE INDEX IF NOT EXISTS DailyForecastDate ON DailyForecast (
    year            DESC,
    month           DESC,
    day_of_month    DESC,
    forecast_key    DESC
);

insert:
REPLACE INTO DailyForecast
    VALUES (?,?,?,?,?,?);

lastPid:
SELECT MAX(pid) FROM DailyForecast;

selectByDateRange:
SELECT * FROM DailyForecast
    WHERE
        forecast_key = ?
        AND year >= ?
        AND month >= ?
        AND day_of_month >= ?
        AND year <= ?
        AND month <= ?
        AND day_of_month <= ? LIMIT 5;

ForecastDbRepositoryImpl:

class ForecastDbRepositoryImpl(private val database: Database): ForecastDbRepository() {

    override suspend fun insertDailyForecast(dailyForecast: DailyForecast): Long {
        return database.transactionWithResult {
            insertForecast(dailyForecast)
        }
    }

    override suspend fun insertDailyForecast(dailyForecasts: List<DailyForecast>): List<Long> {
        return database.transactionWithResult {
            dailyForecasts.map { insertForecast(it) }
        }
    }

    private fun insertForecast(dailyForecast: DailyForecast): Long {
        database.dayliForecastQueries.insert(
            pid = dailyForecast.pid.takeIf { it >= 0L },
            year = dailyForecast.year,
            month = dailyForecast.month,
            day_of_month = dailyForecast.day_of_month,
            hours_of_sun = dailyForecast.hours_of_sun,
            forecast_key = dailyForecast.forecast_key
        )
        return database.dayliForecastQueries.lastPid().executeAsOne().MAX ?: 0L
    }
}

我刚刚亲自测试过,效果很好!

重要补充。如果你想在这个例子中自动递增,你需要使用这样的构造函数:

REPLACE INTO DailyForecast      VALUES (?,?,?,?,?,?);
并将 null 传递给名为 pid 的参数

为了让一切正常工作,您不能使用以下插入说明:

insert:
REPLACE INTO DailyForecast
     VALUES ?;

因为在生成的类中,pid 字段不可为空!

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