You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js+Hapi.js实现MariaDB批量更新插入的格式转换求助

解决方案:表单修正、Payload转换与批量数据库操作

一、修正Handlebars表单的字段名称错误

原表单中opt1至opt5对应的input标签name属性均错误设为opt0,会导致提交数据混乱,修正后的代码如下:

{{#each parlist}}
    <input type="hidden" name="id" value="{{this.id}}" form="form-edit">
    <td style="text-align:center;">{{this.id}}</td>
    <td><input type="text" name="name" value="{{this.name}}" form="form-edit"></td>
    <td><input type="text" name="description" value="{{this.description}}" form="form-edit"></td>
    <td><input type="text" name="opt0" value="{{this.opt0}}" form="form-edit"></td>
    <td><input type="text" name="opt1" value="{{this.opt1}}" form="form-edit"></td>
    <td><input type="text" name="opt2" value="{{this.opt2}}" form="form-edit"></td>
    <td><input type="text" name="opt3" value="{{this.opt3}}" form="form-edit"></td>
    <td><input type="text" name="opt4" value="{{this.opt4}}" form="form-edit"></td>
    <td><input type="text" name="opt5" value="{{this.opt5}}" form="form-edit"></td>
    <td><input type="text" name="multiplier" value="{{this.multiplier}}" form="form-edit"></td>
{{/each}}

二、将req.payload转换为对象数组

提交的payload以字段为键、对应值数组为值,需转换为每行数据对应一个对象的数组,同时处理数据类型转换:

function transformPayload(payload) {
  const rowCount = payload.id.length;
  const result = [];

  for (let i = 0; i < rowCount; i++) {
    result.push({
      id: payload.id[i] ? parseInt(payload.id[i], 10) : null,
      name: payload.name[i],
      description: payload.description[i],
      opt0: payload.opt0[i],
      opt1: payload.opt1[i],
      opt2: payload.opt2[i],
      opt3: payload.opt3[i],
      opt4: payload.opt4[i],
      opt5: payload.opt5[i],
      multiplier: parseFloat(payload.multiplier[i]) || 1
    });
  }

  return result;
}

// 使用示例
const transformedData = transformPayload(req.payload);

转换后的数据格式示例:

[
  { id: 1, name: 'Social', description: 'Desc 1', ..., multiplier: 1 },
  { id: 3, name: 'Work ethic', description: 'Desc 2', ..., multiplier: 1 },
  { id: null, name: 'Dominance', description: 'Desc 3', ..., multiplier: 1 }
]

三、拆分更新与插入数据集

根据id是否为空,将转换后的数据拆分为更新组(已有数据)和插入组(新数据):

const updateItems = transformedData.filter(item => item.id !== null);
const insertItems = transformedData.filter(item => item.id === null);

四、批量操作MariaDB

使用Node.js MariaDB插件实现批量插入和更新,建议用事务保证操作原子性。

批量插入新数据

// 准备插入数据,剔除id字段
const insertValues = insertItems.map(item => {
  const { id, ...rest } = item;
  return Object.values(rest);
});

const insertSql = `
  INSERT INTO parameters (name, description, opt0, opt1, opt2, opt3, opt4, opt5, multiplier)
  VALUES ?
`;

批量更新已有数据

利用MariaDB的CASE语句实现批量更新:

let updateSql = '';
if (updateItems.length > 0) {
  const setClauses = [
    'name = CASE id',
    'description = CASE id',
    'opt0 = CASE id',
    'opt1 = CASE id',
    'opt2 = CASE id',
    'opt3 = CASE id',
    'opt4 = CASE id',
    'opt5 = CASE id',
    'multiplier = CASE id'
  ];
  const ids = [];

  updateItems.forEach(item => {
    ids.push(item.id);
    setClauses[0] += ` WHEN ${item.id} THEN ${connection.escape(item.name)}`;
    setClauses[1] += ` WHEN ${item.id} THEN ${connection.escape(item.description)}`;
    setClauses[2] += ` WHEN ${item.id} THEN ${connection.escape(item.opt0)}`;
    setClauses[3] += ` WHEN ${item.id} THEN ${connection.escape(item.opt1)}`;
    setClauses[4] += ` WHEN ${item.id} THEN ${connection.escape(item.opt2)}`;
    setClauses[5] += ` WHEN ${item.id} THEN ${connection.escape(item.opt3)}`;
    setClauses[6] += ` WHEN ${item.id} THEN ${connection.escape(item.opt4)}`;
    setClauses[7] += ` WHEN ${item.id} THEN ${connection.escape(item.opt5)}`;
    setClauses[8] += ` WHEN ${item.id} THEN ${item.multiplier}`;
  });

  const finalSet = setClauses.map(clause => `${clause} END`).join(', ');
  updateSql = `UPDATE parameters SET ${finalSet} WHERE id IN (${ids.join(', ')})`;
}

事务执行

try {
  await connection.beginTransaction();
  
  if (insertItems.length > 0) {
    await connection.query(insertSql, [insertValues]);
  }
  
  if (updateItems.length > 0) {
    await connection.query(updateSql);
  }
  
  await connection.commit();
} catch (err) {
  await connection.rollback();
  throw err;
}

内容的提问来源于stack exchange,提问作者LKE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 19:17:32