有没有办法在`sqlx :: query!“中使用动态查询

问题描述

上下文:锈,库sqlx

问题:如何在不丢失类型检查的情况下从较小的部分组成类似的查询?

macro_rules! select {
  () => {"select col from tab"}
}

macro_rules! guard1 {
  () => {"where col > 1"}
}

macro_rules! guard2 {
  () => {"where col > 2"}
}

let mut conn = get_pg_connection_from_somewhere();

if some_condition() {
  sqlx::query!(select!() + guard1!()).fetch_all(&mut conn).await?;
} else {
  sqlx::query!(select!() + guard2!()).fetch_all(&mut conn).await?;
}

文档说:

查询必须是字符串文字,或使用+的字符串文字串联(对于由宏生成的查询很有用),否则它不能被自省(因此不能是动态的或另一个宏的结果)。

您会看到它说“对宏生成的查询很有用”(尽管以后“不能是另一个宏的结果”)

我要解决的问题是,根据条件,我想运行不同但相似的查询(例如,它们都具有相同的列),并且我希望由较小的可重用部分组成查询[

解决方法

您可以使用如下宏来执行此操作

macro_rules! fetch_all_todos_with_predicate {
    ($executor:ident,$predicate:tt) => {
        sqlx::query!(
            "SELECT id,title,completed_at FROM todos " + $predicate
        ).fetch_all($executor).await
    }
}

并根据某些条件提供谓词

let kind = QueryKind::Complete;
let mut conn = get_pg_connection_from_somewhere();

let result = match kind {
    QueryKind::Complete => fetch_all_todos_with_predicate!(conn,"WHERE completed_at IS NOT NULL"),QueryKind::Incomplete => fetch_all_todos_with_predicate!(conn,"WHERE completed_at IS NULL"),QueryKind::All => fetch_all_todos_with_predicate!(conn,""),};

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...