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

如何用JavaScript HTTP请求在Dataverse表中批量插入多条记录

PowerApps模型驱动应用中JS Web Resource批量插入记录的正确实现

优先方案:使用官方executeMultiple API

Dataverse Web API提供了executeMultiple方法,专门用于批量操作,无需手动构建复杂的OData批量请求体,是最可靠的实现方式,能避免绝大多数格式错误。

代码示例

async function batchCreateRecords() {
    // 构建批量请求数组,每条请求对应一个要插入的记录
    const batchRequests = [
        Xrm.WebApi.online.createRequest("accounts", { 
            name: "测试账户1", 
            telephone1: "1234567890" 
        }),
        Xrm.WebApi.online.createRequest("accounts", { 
            name: "测试账户2", 
            telephone1: "0987654321" 
        })
        // 可添加更多记录请求
    ];

    try {
        // 执行批量操作:continueOnError=false表示事务性(一个失败则全部回滚),true表示忽略错误继续执行
        const operationResults = await Xrm.WebApi.online.executeMultiple(batchRequests, { continueOnError: false });

        // 处理结果
        let successCount = 0;
        operationResults.forEach(result => {
            if (result.success) {
                successCount++;
                console.log(`记录创建成功,ID: ${result.id}`);
            } else {
                console.error(`创建失败: ${result.error.message}`);
            }
        });

        Xrm.Navigation.openAlertDialog({ 
            text: `批量操作完成,成功插入${successCount}/${batchRequests.length}条记录` 
        });
    } catch (error) {
        console.error("批量操作异常:", error);
        Xrm.Navigation.openAlertDialog({ 
            text: `批量操作失败: ${error.message}` 
        });
    }
}

关键说明

  • 第一个参数是请求数组,每个请求用createRequest创建,指定实体逻辑名称和记录数据
  • continueOnError参数控制事务行为:
    • false:事务性操作,任一请求失败则所有操作回滚
    • true:非事务性,即使部分请求失败,其他请求仍会执行
  • 返回结果包含每个操作的成功状态、记录ID(成功时)和错误信息(失败时)

备选方案:手动构建OData $batch请求

如果因特殊需求必须手动使用OData批量端点,需严格遵循OData 4.0规范,重点注意CRLF换行符和multipart/mixed格式(这是你之前出现请求头格式错误的核心原因)。

代码示例

async function batchCreateViaODataBatch() {
    const globalContext = Xrm.Utility.getGlobalContext();
    const clientUrl = globalContext.getClientUrl();
    const apiVersion = "v9.2";
    // 生成唯一的batch边界字符串,避免与请求体内容冲突
    const batchBoundary = `batch_${Math.random().toString(36).slice(2)}`;

    // 准备要插入的记录数据
    const records = [
        { name: "测试账户1", telephone1: "1234567890" },
        { name: "测试账户2", telephone1: "0987654321" }
    ];

    // 构建批量请求体,必须使用CRLF(\r\n)分隔内容
    let batchBody = "";
    records.forEach(record => {
        const changeSetId = `changeset_${Math.random().toString(36).slice(2)}`;
        // 开始batch的一个part
        batchBody += `--${batchBoundary}\r\n`;
        batchBody += `Content-Type: multipart/mixed; boundary=${changeSetId}\r\n\r\n`;
        
        // 添加单个创建请求到变更集
        batchBody += `--${changeSetId}\r\n`;
        batchBody += `Content-Type: application/http\r\n`;
        batchBody += `Content-Transfer-Encoding: binary\r\n\r\n`;
        batchBody += `POST ${clientUrl}/api/data/${apiVersion}/accounts HTTP/1.1\r\n`;
        batchBody += `Content-Type: application/json\r\n\r\n`;
        batchBody += `${JSON.stringify(record)}\r\n\r\n`;
        
        // 结束当前变更集
        batchBody += `--${changeSetId}--\r\n`;
    });
    // 结束整个batch
    batchBody += `--${batchBoundary}--`;

    try {
        // 获取当前用户的访问令牌
        const authToken = await Xrm.WebApi.getAccessToken(clientUrl);
        const response = await fetch(`${clientUrl}/api/data/${apiVersion}/$batch`, {
            method: "POST",
            headers: {
                "Authorization": `Bearer ${authToken}`,
                "Content-Type": `multipart/mixed; boundary=${batchBoundary}`,
                "Accept": "application/json"
            },
            body: batchBody
        });

        if (!response.ok) {
            const errorDetail = await response.text();
            throw new Error(`批量请求失败: ${errorDetail}`);
        }

        const responseContent = await response.text();
        console.log("批量插入成功", responseContent);
        Xrm.Navigation.openAlertDialog({ text: "多条记录已成功插入" });
    } catch (error) {
        console.error("批量插入出错:", error);
        Xrm.Navigation.openAlertDialog({ text: `插入失败: ${error.message}` });
    }
}

核心注意事项

  • 换行符必须用CRLF(\r\n):HTTP协议要求请求头和内容之间用CRLF分隔,使用单个\n会触发请求头格式错误
  • boundary字符串唯一:必须确保batch和changeset的边界字符串不会出现在请求体的任何内容中,建议用随机字符串生成
  • 变更集事务性:每个changeset内的操作是原子性的,要么全部成功,要么全部回滚;如果不需要事务,可将每个操作放在独立的changeset中
  • API版本匹配:确保使用的API版本与当前环境兼容(如v9.2)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 09:15:01