如何在Diesel中使用SQL的NOW()字面量实现插入/更新操作?
如何在Diesel中使用SQL的NOW()字面量实现插入/更新操作?
我刚好处理过类似的需求,用Diesel实现这个其实很直接,咱们分插入和更新两种场景来一步步说:
首先要明确:咱们的目标是让生成的SQL语句里直接出现NOW(),而不是由Rust客户端生成时间戳再传给数据库,所以不能直接给event_date字段赋值chrono::NaiveDateTime实例,得用Diesel提供的表达式能力来嵌入数据库函数。
一、插入记录时使用NOW()
咱们结合你给出的schema和模型结构来写示例:
方式1:用Diesel内置的类型安全函数(推荐)
Diesel针对PostgreSQL提供了内置的now()函数,类型安全,不会有SQL注入风险,需要先导入对应的模块:
use diesel::pg::expression::dsl::now; use diesel::RunQueryDsl; // 确保导入execute需要的trait
然后在插入时,显式指定字段的值为now():
// 注意:这里MyTable的event_date可以随便填个默认值,因为后面会被表达式覆盖 let new_entry = MyTable { id: 456, // 这里如果是自增ID,可以去掉或者用数据库自增逻辑 event_date: chrono::NaiveDateTime::from_timestamp(0, 0), }; insert_into(mytable::table) .values(( mytable::id.eq(new_entry.id), mytable::event_date.eq(now()), // 这里用内置的now()函数 )) .execute(&your_db_connection) .expect("插入记录失败");
生成的SQL会是类似这样的(完全符合你的需求):
INSERT INTO mytable (id, event_date) VALUES ($1, NOW())
方式2:直接使用SQL字面量
如果不想导入PG专属的模块,也可以直接嵌入NOW()字面量,用Diesel的sql函数:
use diesel::expression::sql_literal::sql; use diesel::RunQueryDsl; insert_into(mytable::table) .values(( mytable::id.eq(456), mytable::event_date.eq(sql("NOW()")), )) .execute(&your_db_connection) .unwrap();
这种方式更灵活,但要注意确保SQL字面量的正确性,避免拼写错误。
二、更新记录时使用NOW()
更新的逻辑和插入类似,同样可以用两种方式:
方式1:内置函数版
use diesel::pg::expression::dsl::now; use diesel::RunQueryDsl; update(mytable::table) .filter(mytable::id.eq(456)) // 筛选要更新的记录 .set(mytable::event_date.eq(now())) .execute(&your_db_connection) .expect("更新记录失败");
方式2:SQL字面量版
use diesel::expression::sql_literal::sql; use diesel::RunQueryDsl; update(mytable::table) .filter(mytable::id.eq(456)) .set(mytable::event_date.eq(sql("NOW()"))) .execute(&your_db_connection) .unwrap();
小提示
- 如果你的
id是数据库自增的,插入时可以不用指定id字段,直接省略mytable::id.eq(...)这一行,让数据库自动生成ID。 - 两种方式里,优先用内置的
now()函数,因为它是类型安全的,Diesel会自动帮你处理类型匹配,避免因为字段类型不匹配导致的错误。
内容来源于stack exchange
相关产品推荐
相关产品推荐

