【问题标题】:Is there a way to use dynamic query in `sqlx::query!()"有没有办法在 `sqlx::query!()" 中使用动态查询
【发布时间】:2021-07-14 01:10:20
【问题描述】:

上下文:rust,库 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?;
}

文档说:

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

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

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

【问题讨论】:

    标签: rust rust-sqlx


    【解决方案1】:

    你可以使用下面的宏来做到这一点

    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, ""),
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-15
      • 2016-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      相关资源
      最近更新 更多