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

Python遍历字典按字段类型拼接SQL的循环逻辑问题

按字段类型动态拼接MERGE SQL的实现方案

问题背景

  • 首先通过如下代码获取表结构字段字典,字典键为字段名,值为字段类型:
try:
    columns = get_table_columns(table, cursor)
    print(columns)
except Exception as e:
    # 原有异常处理逻辑
    pass
  • 字典结构示例:
{'EFF_DT': 'DATE', 'TERM_DT': 'DATE', 'PACKAGE_LABEL': 'TEXT'}
  • 需求规则:拼接MERGE语句时,所有类型为DATE的字段(包含主键字段),需要对临时表侧的字段值包裹TO_DATE(..., 'DD/MM/YYYY')做日期转换,非DATE类型字段直接按原逻辑拼接。
  • 原有代码已经实现了UPDATE分支、INSERT分支的DATE类型字段处理,但主键关联(ON子句)部分未做类型适配,直接嵌套循环判断会产生冗余遍历,导致SQL语法错误。原有问题代码如下:
for key in primary_keys:
        sql += '{table}."{key}" = {temp_table}."{key}"'.format(
            table=table, temp_table=temp_table, key=key
        )
        if key == primary_keys[-1]:
            continue
        sql += " and "

    sql += " WHEN MATCHED THEN  update set "

    for column in columns:
        if columns[column]=="DATE":
            sql+="{table}.\"{column}\" = TO_DATE({temp_table}.\"{column}\", 'DD/MM/YYYY'), ".format(table=table, temp_table=temp_table, column=column)
            continue
        sql+= "{table}.\"{column}\" = {temp_table}.\"{column}\", ".format(table=table, temp_table=temp_table, column=column)
    sql = sql[:-2]
    sql+= " when not matched then insert values ( "

    for column in columns:
        if columns[column]=="DATE":
            sql+="TO_DATE("+table+"_TEMP.\""+column+"\", 'DD/MM/YYYY')"
        else:
            sql+= table+"_TEMP.\""+column+"\""
        if column ==list(columns.keys())[-1]:
            sql += " );"
            continue
        sql+=", "

优化实现方案

核心思路:不需要嵌套循环,遍历主键时直接从已有的columns字典中查询当前主键的类型即可,字典键查询时间复杂度为O(1),无冗余遍历问题。同时抽离公共字段转换逻辑,替换手动拼接逗号的易出错写法。

优化后完整代码

# 抽离公共字段表达式生成逻辑,三处拼接场景复用,避免重复写判断
def gen_field_expr(table_alias: str, col_name: str, col_type_map: dict) -> str:
    col_type = col_type_map.get(col_name)
    if col_type == "DATE":
        # DATE类型对临时表侧字段做TO_DATE转换
        return f"TO_DATE({table_alias}.\"{col_name}\", 'DD/MM/YYYY')"
    # 非DATE类型直接返回字段引用
    return f"{table_alias}.\"{col_name}\""

# 1. 拼接ON子句主键关联条件
on_clauses = []
for pk in primary_keys:
    # 主表字段本身是结构化存储的DATE类型,不需要转换
    left_expr = f'{table}."{pk}"'
    # 临时表字段按类型规则生成表达式
    right_expr = gen_field_expr(temp_table, pk, columns)
    on_clauses.append(f"{left_expr} = {right_expr}")
sql += " AND ".join(on_clauses)

# 2. 拼接MATCHED时的UPDATE分支
sql += " WHEN MATCHED THEN UPDATE SET "
update_clauses = []
for col in columns:
    left_expr = f'{table}."{col}"'
    right_expr = gen_field_expr(temp_table, col, columns)
    update_clauses.append(f"{left_expr} = {right_expr}")
sql += ", ".join(update_clauses)

# 3. 拼接NOT MATCHED时的INSERT分支
sql += " WHEN NOT MATCHED THEN INSERT VALUES ( "
insert_value_exprs = []
for col in columns:
    insert_value_exprs.append(gen_field_expr(f"{table}_TEMP", col, columns))
sql += ", ".join(insert_value_exprs)
sql += ");"

方案优势

  • 无冗余循环:主键遍历过程直接通过字典查询字段类型,不存在嵌套遍历的性能问题和逻辑错误
  • 易维护:字段类型转换逻辑统一收敛在gen_field_expr函数中,后续如果需要新增TIMESTAMP、数值格式化等其他类型处理,只需要修改这一处代码即可
  • 语法更稳定:替换了原代码中通过sql[:-2]截断末尾逗号的写法,改用列表收集SQL片段后通过join拼接分隔符,从根源避免多余逗号、漏拼分隔符导致的SQL语法错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 13:57:13