简体   繁体   中英

How to convert ADO.NET SQL Server parametrized query to ORACLE query (in Regex)?

Queries can be like:

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

If better option than regex is available I'm open for suggestions. There must be a method/delegate, that actually adds the DbParameter for DbCommand when match is found. This is just way beyond my regex skills.

EDIT: Actually I would be very happy to restrict this to only =, <, >, >=, <= in a way that column can be only 1 time. So leaving IN, NOT IN and BETWEEN out of this. More complex queries can be made other way (explained in comment).

-m

Ok. I did very basic implementation, but if someone has to do this he might get the idea in the most basic case. Here the query is written in oracle format and in case of sql-server we change the : "placeholder" to @.

    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;
    }

used like this:

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

here cmd is my own abstraction of DbCommand-class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM