如何使用Node.js在SQL中创建不限数量的父子关联动态表
Node.js 动态生成父子关联表SQL实现方案
你原有平级字段的建表逻辑可以直接复用,只需要新增嵌套分组识别、子表SQL生成两个模块即可,无需重构现有代码。
配置结构约定
首先统一传入的JSON配置规则,区分平级父表字段和嵌套子表分组,示例配置如下:
{ "parentTableName": "OrderMain", "parentBusinessFields": [ {"name": "OrderNo", "type": "varchar(64) NOT NULL"}, {"name": "TotalAmount", "type": "decimal(18,2) DEFAULT 0"}, {"name": "OrderStatus", "type": "tinyint DEFAULT 0"} ], "childTableGroups": { "MustansarAdvanceGroup": [ {"name": "AdvancePayAmount", "type": "decimal(18,2)"}, {"name": "AdvancePayTime", "type": "datetime"} ], "MustansarBasicGroup": [ {"name": "GoodsName", "type": "varchar(128) NOT NULL"}, {"name": "GoodsCount", "type": "int DEFAULT 1"}, {"name": "UnitPrice", "type": "decimal(18,2)"} ] } }
公共基础字段(Id、IsActive、审计字段等)可以直接内置在代码逻辑中,无需每次在配置中重复编写。
核心实现代码
const DEFAULT_PARENT_FIELDS = [ {name: "Id", type: "int IDENTITY(1,1) PRIMARY KEY"}, {name: "IsActive", "type:": "bit DEFAULT 1"}, {name: "CreatedBy", "type": "int"}, {name: "UpdatedBy", "type": "int"}, {name: "CreatedAt", "type": "datetime DEFAULT GETDATE()"}, {name: "UpdatedAt", "type": "datetime"} ]; /** * 生成全量建表SQL * @param {Object} config 表配置 * @returns {string[]} 按执行顺序排列的建表SQL数组(父表在前,子表在后) */ function buildCreateTableSQL(config) { const sqlList = []; const { parentTableName, parentBusinessFields = [], childTableGroups = {} } = config; // 生成父表SQL(可直接复用你原有平级字段处理逻辑) const parentAllFields = [...DEFAULT_PARENT_FIELDS, ...parentBusinessFields]; const parentFieldSegment = parentAllFields .map(field => ` ${field.name} ${field.type}`) .join(',\n'); sqlList.push(`CREATE TABLE ${parentTableName} (\n${parentFieldSegment}\n);`); // 遍历所有子表分组,逐个生成子表SQL Object.entries(childTableGroups).forEach(([groupName, groupFields]) => { // 子表名可根据自身命名规范调整,这里默认用 父表名_分组名 格式避免重名 const childTableName = `${parentTableName}_${groupName.replace('Group', '')}`; // 子表固定字段:自身主键 + 关联父表的外键 const childBaseFields = [ {name: "Id", type: "int IDENTITY(1,1) PRIMARY KEY"}, {name: "ParentId", type: `int NOT NULL FOREIGN KEY REFERENCES ${parentTableName}(Id)`} ]; const childAllFields = [...childBaseFields, ...groupFields]; const childFieldSegment = childAllFields .map(field => ` ${field.name} ${field.type}`) .join(',\n'); sqlList.push(`CREATE TABLE ${childTableName} (\n${childFieldSegment}\n);`); }); return sqlList; }
使用方式
// 传入配置获取所有建表语句 const tableConfig = require('./your-config-path.json'); const sqlStatements = buildCreateTableSQL(tableConfig); // 按顺序执行SQL即可,注意必须先执行父表SQL再执行子表,否则外键约束会创建失败 sqlStatements.forEach(sql => { // 替换为你实际使用的数据库驱动执行方法,例如 mssql.query(sql) / mysql.query(sql) console.log('执行建表SQL:\n', sql); });
适配说明
- 如果使用MySQL而非SQL Server,只需要调整字段类型、自增、外键的语法即可,核心遍历逻辑完全不变
- 如果需要支持多级嵌套子表(子表下再挂子表),只需把当前子表生成逻辑改成递归调用,外键关联逻辑和一级子表一致,无层级/数量限制
- 子表名规则、默认字段配置都可以根据业务需求自行调整,不影响核心逻辑
内容的提问来源于stack exchange,提问作者ADEEL FAROOQ
相关产品推荐
相关产品推荐

