如何使用diesel执行“updatefrom”?

xj3cbfub  于 2021-07-24  发布在  Java
关注(0)|答案(1)|浏览(359)

假设我有三张table, a , b 以及 c :

  1. create table c (
  2. id serial primary key,
  3. can_edit_b boolean not null
  4. );
  5. create table b (
  6. id serial primary key,
  7. value text not null
  8. );
  9. create table a (
  10. id serial primary key,
  11. c_id integer not null references c(id),
  12. b_id integer not null references b(id)
  13. );

我想更新一下 b (给定 c )只要 c 由的示例引用 a 其中也提到 b 以及 c.can_edit_b 这是真的。我要执行的sql:

  1. update b
  2. set value = "some value"
  3. from c, a
  4. where a.b_id == b.id
  5. where a.c_id == <user id (inserted as a Rust i32)>
  6. where c.can_edit_b == true

我在diesel的api中找不到对应于sql的相关方法/函数 from . 如果我尝试使用 inner_join 然后编译器告诉我 inner_join 未定义 UpdateStatement .

neekobn8

neekobn81#

可以联接表,应用筛选器,然后将其用作更新条件:

  1. # [macro_use]
  2. extern crate diesel; // 1.4.5, features = ["postgres"]
  3. use diesel::prelude::*;
  4. table! {
  5. a {
  6. id -> Integer,
  7. c_id -> Integer,
  8. b_id -> Integer,
  9. }
  10. }
  11. table! {
  12. b {
  13. id -> Integer,
  14. value -> VarChar,
  15. }
  16. }
  17. table! {
  18. c {
  19. id -> Integer,
  20. can_edit_b -> Bool,
  21. }
  22. }
  23. joinable!(a -> b (b_id));
  24. joinable!(a -> c (c_id));
  25. allow_tables_to_appear_in_same_query!(a, b, c);
  26. fn example(arg: i32) {
  27. let all_joined = a::table.inner_join(b::table).inner_join(c::table);
  28. let matching_rows = all_joined
  29. .filter(a::c_id.eq(arg))
  30. .filter(c::can_edit_b.eq(true));
  31. let update_stmt = diesel::update(b::table)
  32. .filter(b::id.eq_any(matching_rows.select(b::id)))
  33. .set(b::value.eq("some value"));
  34. println!("{}", diesel::debug_query::<diesel::pg::Pg, _>(&update_stmt));
  35. }
  36. fn main() {
  37. example(42);
  38. }

这将生成与您的不同的sql,但结果应该相同:

  1. UPDATE "b"
  2. SET "value" = $1
  3. WHERE "b"."id" IN
  4. (SELECT "b"."id"
  5. FROM (("a"
  6. INNER JOIN "b" ON "a"."b_id" = "b"."id")
  7. INNER JOIN "c" ON "a"."c_id" = "c"."id")
  8. WHERE "a"."c_id" = $2
  9. AND "c"."can_edit_b" = $3) -- binds: ["some value", 42, true]

另请参见:
如何在diesel中对postgres数据库执行delete with sub查询?

展开查看全部

相关问题