[ PROMPT_NODE_24056 ]
D1 API 参考
[ SKILL_DOCUMENTATION ]
# D1 API 参考
## 预处理语句(安全性要求)
typescript
// ❌ 错误:直接字符串插值(存在 SQL 注入风险)
const result = await env.DB.prepare(`SELECT * FROM users WHERE id = ${userId}`).all();
// ✅ 正确:使用 bind() 的预处理语句
const result = await env.DB.prepare('SELECT * FROM users WHERE id = ?').bind(userId).all();
// 多个参数
const result = await env.DB.prepare('SELECT * FROM users WHERE email = ? AND active = ?').bind(email, true).all();
## 查询执行方法
typescript
// .all() - 返回所有行
const { results, success, meta } = await env.DB.prepare('SELECT * FROM users WHERE active = ?').bind(true).all();
// results: 行对象数组; success: 布尔值
// meta: { duration: 数字, rows_read: 数字, rows_written: 数字 }
// .first() - 返回第一行或 null
const user = await env.DB.prepare('SELECT * FROM users WHERE id = ?').bind(userId).first();
// .first(columnName) - 返回单列值
const email = await env.DB.prepare('SELECT email FROM users WHERE id = ?').bind(userId).first('email');
// 返回 string | number | null
// .run() - 用于 INSERT/UPDATE/DELETE(不返回行数据)
const result = await env.DB.prepare('UPDATE users SET last_login = ? WHERE id = ?').bind(Date.now(), userId).run();
// result.meta: { duration, rows_read, rows_written, last_row_id, changes }
// .raw() - 返回数组的数组(对大数据集高效)
const rawResults = await env.DB.prepare('SELECT id, name FROM users').raw();
// [[1, 'Alice'], [2, 'Bob']]
## 批量操作
typescript
// 在单次往返中执行多个查询(原子事务)
const results = await env.DB.batch([
env.DB.prepare('SELECT * FROM users WHERE id = ?').bind(1),
env.DB.prepare('SELECT * FROM posts WHERE author_id = ?').bind(1),
env.DB.prepare('UPDATE users SET last_access = ? WHERE id = ?').bind(Date.now(), 1)
]);
// results 是数组: [result1, result2, result3]
// 使用相同预处理语句但不同参数的批量操作
const userIds = [1, 2, 3];
const stmt = env.DB.prepare('SELECT * FROM users WHERE id = ?');
const results = await env.DB.batch(userIds.map(id => stmt.bind(id)));
## 事务(通过 batch)
typescript
// D1 将 batch() 作为原子事务执行 - 全部成功或全部失败
const results = await env.DB.batch([
env.DB.prepare('INSERT INTO accounts (id, balance) VALUES (?, ?)').bind(1, 100),
env.DB.prepare('INSERT INTO accounts (id, balance) "