---
order: 16
navTitle: 脚本
---
# 加工组件：脚本

脚本组件是使用脚本进行加工一些难以用SQL实现的逻辑，实现对数据表的转换。

如将JSON格式的数据转化为多个字段：

![脚本示例](./images/2019-12-27-11-57-53.png)

示例地址：[脚本](https://demo.succbi.com/v5/DEMO/data?:open=YuDsNh6mhFIA7ol1XHXuUD)

```ts
/**
* 脚本返回类型，必须定义，后台会根据返回结果做不同处理
* 1. Table，在物理表基础上再做加工
* 2. Sql，在sql基础上再做加工
* 3. Stream，流式加工数据
* 4. None，无结果
*/
function getReturnType(): ScriptNodeDataType {
    return ScriptNodeDataType.Stream;
}

/**
 * 脚本节点的执行入口。下面几种情况会触发脚本节点的执行：
 * 1. 后端定时调度加工模型
 * 2. 用户手工调度加工模型
 * 3. 前端用户预览脚本节点的数据
 */
function onProcessScriptNode(context: IDataFlowScriptNodeContext): void {
    //在这里输入脚本节点的业务逻辑代码
    let inputData = context.getInput();
    let outputData = context.getOutput();
    // 可直接将前序节点的字段设置到输出字段中,然后将多的给删掉
    outputData.setFields(inputData.getFields());
    outputData.removeField("TITLE");
    outputData.removeField("CAST");

    // 可直接传入值
    outputData.addField("cast_id", FieldDataType.I);
    outputData.addField("character");
    // 可传入一个json
    outputData.addField({ name: "gender", dataType: FieldDataType.I });
    outputData.addField({ name: "credit_id" }, 3);
    // 可添加多个字段
    outputData.addFields([{ name: "name" }, { name: "order", dataType: FieldDataType.I }]);

    // 先将所有的字段顺序定下来，避免存储数据时重复查找字段
    let fields: DbFieldInfo[] = outputData.getFields() || [];
    let fieldCount = fields.length;
    // 定义在这里，复用一个行对象，节省内存
    let outRow: any[] = new Array(fieldCount);
    // 读取前2行数据进行转换,测试
    for (let i = 0; i < 2; i++) {
        let srcRow = inputData.nextRow();
        let castObj = JSON.parse(srcRow[2]);
        castObj.forEach(data => {
            outRow[0] = srcRow[1];
            for (let j = 1; j < fieldCount; j++) {
                outRow[j] = data[fields[j].name];
            }
            outputData.writeRow(outRow);
        });
    }
}
```

更多脚本及实例可参考：[数据加工脚本组件](../../dev/script/backend/etl-script-node.md)
