如何将ADO.NET SQL Server参数化查询转换为ORACLE查询(在Regex中)?

时间:2014-11-11 16:52:04

标签: c# sql-server regex oracle ado.net

查询可以是:

SELECT * FROM ATable WHERE AColumn = @AColumn;
SELECT * FROM ATable WHERE AColumn >= @AColumn;
SELECT * FROM ATable WHERE AColumn BETWEEN @AColumn1 AND @AColumn2; //not necessary to support

如果有比正则表达式更好的选项,我可以提供建议。必须有一个方法/委托,实际上在找到匹配时为DbParameter添加DbCommand。这远远超出了我的正则表达式技能。

编辑: 实际上,我非常乐意将此限制为仅限于=,<,>,> =,< =这样,该列只能是一次。所以留下IN,而不是IN和BETWEEN。可以通过其他方式进行更复杂的查询(在评论中解释)。

-m

1 个答案:

答案 0 :(得分:0)

确定。我做了非常基本的实现,但如果有人必须这样做,他可能会在最基本的情况下得到这个想法。这里的查询是用oracle格式编写的,如果是sql-server,我们改变:"占位符"到@。

    public void AddParameters(string query, List<object> valueList)
    {
        int orderNr = 0;

        string newQuery = Regex.Replace(query, @"(?<Operator>=|<=|>=|<|>)\s?(?<PlaceHolder>:)(?<ColumnName>([A-Za-z0-9\-]+))",
            new MatchEvaluator(
                delegate(Match match)
                {
                    var param = this.ProviderFactory.CreateParameter();
                    param.ParameterName = match.Groups["ColumnName"].Value;
                    param.DbType = GetDbType(valueList[orderNr]);
                    param.Value = valueList[orderNr++];
                    Parameters.Add(param);

                    if (ProviderType == DbProviderType.SqlServer)
                        return string.Format("{0}@{1}", match.Groups["Operator"].Value, match.Groups["ColumnName"]); 

                    return match.Value;
                }
        ));
    }

    private DbType GetDbType(object value)
    {
        if (value is int)
            return DbType.Int32;
        else if (value is double)
            return DbType.Double;
        else if (value is string)
            return DbType.String;
        else 
            return DbType.DateTime;
    }

像这样使用:

query = "SELECT * FROM ATable WHERE ColumnA=:ColumnA AND ColumnB=ColumnB AND (LanguageId=:LANGUAGEID OR LanguageId = '*')";
cmd.AddParameters(query, new List<object> { tableId, fieldName, languageId });

这里cmd是我自己的DbCommand-class抽象。