获取转义的多语法 sql 更新字符串

Posted

技术标签:

【中文标题】获取转义的多语法 sql 更新字符串【英文标题】:Get an escaped multi syntax sql update string 【发布时间】:2014-11-24 04:50:16 【问题描述】:

我正在为 Enterprise Architect 编写插件,我需要操作内部脚本。 我想将自己的函数添加到现有脚本中。

脚本存储在脚本列中的t_script表中。

不幸的是,脚本没有在 API 中公开,所以我必须解决这个问题并使用数据库上的更新查询来更新脚本。

问题是脚本倾向于使用大量字符,在 sql 更新查询中使用它们时可能会造成问题,但我不太热衷于编写自己的转义函数。

所以我尝试的是这个

public void addCode(string functionCode)

    this._code += functionCode;
    SqlCommand sqlCommand = new SqlCommand("update t_script set script = @functionCode where ScriptID = " + this.scriptID );
    sqlCommand.Parameters.AddWithValue("@functionCode",this._code);
    this.model.executeSQL(sqlCommand.CommandText);

我希望 sqlCommand.CommandText 能给我将要执行的实际 sql 字符串,但它没有。它基本上仍然是我创建它时使用的相同字符串,并且没有替换“@functionCode”。

另一个困难是我的 SQL 字符串需要适用于 EA 支持的所有 DBMS 类型

SQL Server 2000、2005、2008 和 2012 mysql Oracle 9i、10g、11g 和 12c PostgreSQL MSDE Sybase Adaptive Server Anywhere MS 访问 OpenEdge 进展 火鸟

有没有人有比自己编写转义函数更好的解决方案?

【问题讨论】:

期待预期的 ;-) 当然,您可以要求 Sparxians 提供他们的内部程序。可能与要求教皇犯错误一样。所以在此期间做你所期望的:写你自己的东西>:-( 我认为唯一真正安全和理智的方法是在 Select 中使用绑定变量。你不需要转义。 - 您只需将变量保存在某处... @Falco 你是什么意思?问题是我需要一个完整的 SQL 字符串来传递给 Repository 对象。我无法控制字符串的实际执行。 【参考方案1】:

因为我并没有真正找到某种现有功能,所以我不得不求助于编写自己的转义函数。

这就是我想出的。它似乎可以在 MS-Access、FireBird、SLQ Server、MySQL 和 Oracle 上运行(其他的我没有测试过)

/// <summary>
/// escapes a literal string so it can be inserted using sql
/// </summary>
/// <param name="sqlString">the string to be escaped</param>
/// <returns>the escaped string</returns>
public string escapeSQLString(string sqlString)

    string escapedString = sqlString;
    switch ( this.repositoryType) 
    
        case RepositoryType.MYSQL:
        case RepositoryType.POSTGRES:
            // replace backslash "\" by double backslash "\\"
            escapedString = escapedString.Replace(@"\",@"\\");
        break;
    
    // ALL DBMS types: replace the single qoutes "'" by double single quotes "''"
    escapedString = escapedString.Replace("'","''");
    return escapedString;

编辑:在关注反斜杠转义的 cmets 后修复了代码

【讨论】:

你确定这行得通吗?反斜杠不是 Oracle 字符串中的转义字符!如果我想在 Oracle 中插入 Test'\,请将其替换为 INSERT 'Test''\\' 它将插入两次反斜杠! @Falco 不,我不确定。我必须承认我没有在 Oracle 上测试过反斜杠部分。感谢您的提示。我会测试它并报告。 我认为唯一正确的方法是使用Repository.RepositoryType() 函数来确定SQL 风格,然后使用字符串连接运算符和ascii to char 函数来构建字符串文字。对于使用的每个 SQL 引擎,它们会有所不同 @Falco 我修复了代码示例。据我所知,只有在 MySQL 和 Postgres 中才需要转义反斜杠 好 - 这应该工作!尽管您仍然可能会遇到问题,但如果插入的值不仅是字符串和数字,而且是日期值 - 我不知道您是否使用这些语句插入日期/时间值。我不知道日期转换的标准如何 - 在 Oracle 中它是 TO_DATE('...','...')【参考方案2】:

我认为您不应该期望 SqlCommand 解析参数,这是在服务器上完成的。

至于多 DBMS 问题,我想看看 NHibernate 之类的东西。这不是你可以在最后一刻才加入的东西,但它确实支持 EA 运行的大多数数据库。

【讨论】:

谢谢你的建议,我去研究一下,不过现在看起来有点像用大炮杀蚊子。 嗯。至少对于 MySQL,您必须在客户端转义 SQL 并将结果移至服务器。 AFAIK 没有什么比“这是带占位符的 SQL,这是参数”之类的了。您使用 mysql_real_query 并将编辑的 SQL 放入。

以上是关于获取转义的多语法 sql 更新字符串的主要内容,如果未能解决你的问题,请参考以下文章

转义字符,SQL 注入

Python语法的转义字符

sql特殊字符怎么转义

PHP mysql_real_escape_string() 函数防SQL注入

带有 JSon 的 GraphQL 和 Python - 未转义字符的语法错误

ES9(2018)String 扩展 标签模板里字符串转义