参数化查询(C#,Oracle):如何生成更易读的表示?

3

我正在使用参数化查询在我的C#代码中与Oracle数据库交互。我该如何以更易读的方式记录这些语句?

假设我有一个参数化查询:

INSERT INTO PERSON (ID, NAME, BIRTHDATE) VALUES (:id, :name, :birthdate)

理想情况下,我希望能够查看替换了所有参数的日志条目,以便将该语句复制并粘贴以备后用。
INSERT INTO PERSON (ID, NAME, BIRTHDATE) VALUES (23, ‘Mike’, TO_DATE('2003/07/09', 'yyyy/mm/dd')

我的当前做法是打印出参数化查询的字符串,然后迭代所有参数并使用ToString()。如果有很多参数,这样写起来有点难以阅读。它会产生类似于以下的东西:

INSERT INTO PERSON (ID, NAME, BIRTHDATE) VALUES (:id, :name, :birthdate) [:id=23, :name=Mike, birthdate=2004/07/09 00:00:00]

我计划采用的另一种方法是使用string.Replace()函数来替换参数占位符。但也许有更好的方法吗?

提前感谢您。

编辑 1:

我想最好提供一些代码示例。

我正在使用以下形式的参数化查询(注意:我正在使用log4net):

        using (OracleConnection connection = new OracleConnection(connectionString))
        using (OracleCommand command = new OracleCommand(statement, connection))
        {
            command.Parameters.AddWithValue(":id", id);
            command.Parameters.AddWithValue(":name", name);
            command.Parameters.AddWithValue(":birthdate", birthdate);
            command.Connection.Open();
            log.DebugFormat("Executing statement: {0}.", command.CommandText);
            // there I would add some more code to iterate over
            // the parameters and print them out
            command.ExecuteNonQuery();
            command.Connection.Close();
        }

我正在寻找一种记录oracle命令对象使用语句的方法。 我目前的方法(请参见问题)还不是很令人满意,因为不太易读。

我希望有一些API(可能甚至在OracleClient命名空间中)可以帮助我解析参数化查询。 我可以进行更复杂的字符串替换或正则表达式,但我想收集一些知识。 我已经做了一些研究,但没有找到什么。

4个回答

3
也许值得看看NHibernate中的做法,源代码中找到名为“GetCommandLogString(IDbCommand command)”的函数,你几乎可以复制/粘贴:p。
protected string GetCommandLogString(IDbCommand command)
{
    string outputText;

    if (command.Parameters.Count == 0)
    {
        outputText = command.CommandText;
    }
    else
    {
        StringBuilder output = new StringBuilder();
        output.Append(command.CommandText);
        output.Append("; ");

        IDataParameter p;
        int count = command.Parameters.Count;
        for (int i = 0; i < count; i++)
        {
            p = (IDataParameter) command.Parameters[i];
            output.Append(string.Format("{0} = '{1}'", p.ParameterName, p.Value));

            if (i + 1 < count)
            {
                output.Append(", ");
            }
        }
        outputText = output.ToString();
    }
    return outputText;
}

2
尝试将此内容存储为可运行语句以供以后使用的问题在于,参数版本与硬编码字符串版本运行方式不同,因为前者不需要内联进行类型转换,例如您不必在字符串参数周围加上引号等。 您需要根据每个参数的类型手动执行此操作。
我不知道您的日志格式是什么,但最好写入日志以运行参数化查询的SQL;即声明必要变量并分配值,然后运行查询。 这会产生更多行(如果避免换行,则为更长的行),但然后您可以直接运行代码,而无需担心自己替换参数。 此外,您的日志条目可抵御SQL注入攻击 :)

感谢您的回答。我正是出于您所提到的原因而使用参数化查询。 如果没有参数化查询,记录这些查询就很容易:只需将它们原封不动地打印出来即可。另一方面,参数化查询在某种程度上会使日志记录变得模糊不清。 - Theo Lenndorff

0

可以使用replace函数。为什么不呢?或者你可以使用string.format()。或正则表达式。或者结合使用。你所需要的只是字符串操作。


0
你可以使用以下方式:
INSERT INTO PERSON (ID, NAME, BIRTHDATE)
   VALUES ('"+id+"', '"+name+"', '"+birthdate+"')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接