我正在尝试使用 sqldelight 插入一个项目,但在插入后也返回该项目的 id。在 sqldelight 中似乎没有办法做到这一点。
我可以在插入后调用类似
SELECT last_insert_rowid();
的内容,但这是前进的最佳方式吗?
您可以将此命令添加到您的 .sq 文件中:
lastInsertRowId:
SELECT last_insert_rowid()
;
它会返回最后插入行的
id
。
请参阅 Github 上的这个 issue 了解更多信息。
这个问题是 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 字段不可为空!