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

PostgreSQL+Typescript如何根据传入JSON动态构造可变SQL增改查询

PostgreSQL + TypeScript 动态字段SQL插入/更新实现

核心思路是通过白名单过滤合法字段,动态拼接SQL片段,避免硬编码字段,同时防止SQL注入。

完整实现代码

import type { QueryResult } from 'pg'; // 若使用pg库可添加该类型定义

// 1. 定义表的允许操作字段白名单,对应user_company_fk表的所有可写字段
const ALLOWED_FIELDS = ['siret', 'name', 'address', 'city'] as const;
type AllowedField = typeof ALLOWED_FIELDS[number];

async function operateCompany(param: Record<string, any>): Promise<QueryResult> {
  // 2. 筛选出合法的、有值的字段
  const validEntries = Object.entries(param).filter(([key]): key is [AllowedField, any] => 
    ALLOWED_FIELDS.includes(key as AllowedField) && param[key] !== undefined
  );

  if (validEntries.length === 0) {
    throw new Error('未传入任何有效字段');
  }

  // 3. 动态生成SQL片段
  const columns = validEntries.map(([key]) => `"${key}"`).join(', ');
  const placeholders = validEntries.map((_, index) => `$${index + 1}`).join(', ');
  const values = validEntries.map(([_, value]) => value);

  // 4. 普通插入场景(仅新增数据,未传字段使用表默认值)
  return db.query(`
    INSERT INTO user_company_fk (${columns})
    VALUES (${placeholders})
  `, values);

  // --- 若需要「存在则更新传入字段、不存在则插入」的UPSERT逻辑,替换上方查询即可 ---
  // const updateSet = validEntries.map(([key], index) => `"${key}" = $${index + 1}`).join(', ');
  // return db.query(`
  //   INSERT INTO user_company_fk (${columns})
  //   VALUES (${placeholders})
  //   ON CONFLICT (siret) DO UPDATE SET ${updateSet}
  // `, values);
}

特性说明

  • 完全匹配需求:仅处理用户传入的合法字段,未传入的字段不会被操作,插入时使用表默认值,更新时保留原有值
  • 可扩展性强:后续需要新增支持的字段,只需在ALLOWED_FIELDS数组中添加对应列名即可
  • 安全:白名单机制完全规避SQL注入风险,所有值通过参数化查询传入,不会直接拼接到SQL中

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 00:57:01