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

如何构建可求值的Ruby SQL模板?解决Postgres转义字符问题

问题描述

我的应用允许管理员定义SQL模板脚本,供用户应用于数据结构。模板存储在Postgres数据库的文本字段中,会与数据结构元数据合并。
预期的模板语句:

CREATE TABLE #{@target.code} ( 
    #{@target.getColList('ORACLE', 'typed')} 
)

求值后应得到目标SQL:

CREATE TABLE DSD_TEST (
AHVN13_1 number,
ALTER_MT_ERFUELLT_1 number,
CANTONS_2_1 varchar2(32),
POPULATION_TYPE_1 varchar2(32)
)

但实际从Postgres文本字段取出的模板语句为:

"CREATE TABLE \#{@target.code} ( \r\n\#{@target.getColList('ORACLE', 'typed')} \r\n)"

已通过 task.statement.gsub("\r\n", '') 去除换行,但无法去除转义字符\,请问如何构建该模板以实现正确求值?

解决方法

1. 清理取出的模板内容

取出的字符串带有前后双引号和转义的\,可以一次性处理:

# 移除前后双引号,再将转义的\#替换为#
cleaned_statement = task.statement.gsub(/^"|"$/, '').gsub('\#', '#')
# 按需处理换行(保留换行可让生成的SQL更易读)
cleaned_statement = cleaned_statement.gsub("\r\n", "\n")

处理后模板里的\#{...}会还原为#{...},符合模板引擎的语法要求。

2. 修正模板存储时的转义问题

出现\#的核心原因是存储时模板被自动转义,需从源头解决:

  • 用ORM(比如ActiveRecord)存储时,关闭自动转义特殊字符的配置;
  • 管理员通过表单输入模板时,确保表单提交逻辑不对#做转义处理;
  • 直接在Postgres中插入模板时,用单引号包裹内容,避免转义:
    INSERT INTO your_table (statement) VALUES ('CREATE TABLE #{@target.code} ( 
        #{@target.getColList('ORACLE', 'typed')} 
    )');
    

3. 确保模板引擎正确解析

从#{}语法判断大概率用的是Ruby ERB,清理后的模板需正确传入上下文求值:

require 'erb'
template = ERB.new(cleaned_statement)
# 确保binding中包含@target对象
generated_sql = template.result(binding)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 13:45:28