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

4 回答 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;
}
于 2009-01-19T23:51:11.710 回答
2

尝试将其存储为可运行语句以供以后使用的问题在于参数版本与硬编码字符串版本的运行方式不同,因为前者不需要内联类型转换,例如您不必加上引号围绕字符串参数等。您需要根据每个参数的类型手动执行此操作。

我不知道您的日志格式是什么,但您最好将 SQL 写入日志以运行参数化查询;即,声明必要的变量并赋值,然后运行查询。它将产生更多行(或更长的行,如果您避免换行符),但是您可以按原样运行代码,您不必担心自己替换参数。另外,您的日志条目可以抵抗 SQL 注入 :)

于 2009-01-17T19:38:46.113 回答
0

好吧,使用替换功能。为什么不?或者你可以使用 string.format()。或正则表达式。或组合。你想要的只是字符串操作。

于 2009-01-18T10:25:25.510 回答
0

你可以这样使用:

INSERT INTO PERSON (ID, NAME, BIRTHDATE)
   VALUES ('"+id+"', '"+name+"', '"+birthdate+"')
于 2009-09-29T09:40:38.513 回答