Параметризованные запросы (C#, Oracle): как создать более удобочитаемое представление?

Я использую параметризованные запросы в своем коде 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();
        }

Я ищу способ выйти из оператора, который использует объект команды оракула. Мои текущие подходы (см. вопрос) пока не очень удовлетворительны, потому что не очень читабельны.

Я надеялся, что будет какой-то API (может быть, что-то даже в пространстве имен OracleClient), который поможет мне разобрать параметризованный запрос. Я мог бы сделать более сложную замену строк или регулярное выражение, но я хотел собрать некоторые знания. Я уже провел некоторые исследования по этому вопросу, но ничего не нашел.


person Theo Lenndorff    schedule 17.01.2009    source источник


Ответы (4)


Возможно, стоит посмотреть, как это делается в NHibernate источник.

Найдите функцию под названием «GetCommandLogString (команда IDbCommand)», которую вы могли бы почти скопировать / вставить: 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;
}
person Brendan Kowitz    schedule 19.01.2009

Проблема с попыткой сохранить это как исполняемый оператор для последующего использования заключается в том, что версия параметра работает иначе, чем версия с жестко закодированной строкой, поскольку первая не требует встроенного приведения типов, например. вам не нужно заключать в кавычки строковые параметры и т. д. Вам нужно будет сделать это вручную в зависимости от типа каждого параметра.

Я не знаю, каков ваш формат журнала, но вам может быть лучше записать в журнал SQL, чтобы вместо этого запустить параметризованный запрос; т. е. объявить необходимые переменные и присвоить значения, а затем запустить запрос. Это сделает больше строк (или длиннее строк, если вы избегаете разрывов строк), но тогда вы можете просто запустить код как есть, и вам не нужно беспокоиться о самостоятельной замене параметров. Кроме того, ваши записи в журнале устойчивы к SQL-инъекциям :)

person Geoff    schedule 17.01.2009
comment
Спасибо за Ваш ответ. Я использую параметризованные запросы именно по той причине, о которой вы упомянули. Если бы не было параметризованных запросов, регистрировать эти запросы было бы легко: просто распечатайте их как есть. С другой стороны, параметризованные запросы каким-то образом скрывают журналы. - person Theo Lenndorff; 17.01.2009

Хорошо используйте функцию замены. Почему нет? Или вы можете использовать string.format(). Или регулярные выражения. Или комбинация. Все, что вам нужно, это манипуляции со строками.

person tuinstoel    schedule 18.01.2009

Вы можете использовать этот способ:

INSERT INTO PERSON (ID, NAME, BIRTHDATE)
   VALUES ('"+id+"', '"+name+"', '"+birthdate+"')
person Community    schedule 29.09.2009