Способ применения запроса после параметров?

В приложении С# я создаю запрос, создавая строку запроса с параметрами, а затем в команду, добавляющую параметры и их значения. Например:

string query = "UPDATE USERS u SET u.username = @PARM_USERNAME " +
               "WHERE u.id = @PARM_USERID ";

command.Parameters.AddWithValue("@PARM_USERNAME", user.username);
command.Parameters.AddWithValue("@PARM_USERID", user.id);

command.Connection.Open();
int res = command.ExecuteNonQuery();

Было бы полезно увидеть запрос с применяемыми параметрами, можно ли это сделать в С#/Visual Studio? Я могу проверить command.CommandText, но он показывает только то же содержимое, что и запрос выше, с там, где есть метки параметров. Если это помогает, это противоречит MySQL.

Ответ 1

Там нет гарантии, что существует такая вещь, как "запрос с применяемыми параметрами". Я надеюсь, что драйвер просто отправит команду как SQL и параметры в соответствующей форме для представления каждого значения. Зачем нужно беспокоиться об экранирующих значениях и т.д., Только для того, чтобы процессор запросов мог их отменить и проанализировать на другой стороне? Это более эффективно и менее рискованно просто передавать данные в двоичном формате некоторого описания.

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

Ответ 2

Если вы хотите увидеть запрос с применяемыми параметрами:

string tmp = command.CommandText.ToString();
foreach (SqlParameter p in cmd.Parameters) {
    tmp = tmp.Replace('@' + p.ParameterName.ToString(),"'" + p.Value.ToString() + "'");
}

tmp будет удерживать запрос с применением параметров. Каждый параметр будет окружен одинарными кавычками.

Конечно, это НЕ безопасно выполнять. Я использую его для целей отладки.

Ответ 3

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

Мой опыт работы с SQL Server, поэтому я не уверен, насколько это применимо к MySQL.

Ответ 4

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

Ответ 5

Если вы хотите использовать инструмент, вы можете попробовать использовать Toad для MySql, у которого есть Profiler, и вы можете видеть, что отправляется сервера.

Ответ 6

ответ @christopher был отличным, но для строковых параметров потребуется ' (одинарная кавычка). лучше всего использовать ниже метод:

  private string getGeneratedSql(SqlCommand cmd)
    {
        string result = cmd.CommandText.ToString();
        foreach (SqlParameter p in cmd.Parameters)
        {
            string isQuted = (p.Value is string) ? "'" : "";
            result = result.Replace('@' + p.ParameterName.ToString(), isQuted + p.Value.ToString() + isQuted);
        }
        return result;
    }

Ответ 7

Я использую это для отладки в HTML. Достаточно времени для тестирования с простой копировальной пастой;


        public static string GetQueryHtml(string query, List<SqlParameter> parameters = null)
        {
            string _return = ""; string _parmStringValue; string _varlenght = "50";
            foreach (SqlParameter parameter in parameters)
            {
                if (parameter.SqlDbType == SqlDbType.DateTime)
                {
                    _parmStringValue = "'" + ((DateTime)parameter.Value).ToString("yyyy-MM-dd hh:mm:ss") + "'";
                    _return += Environment.NewLine +  "DECLARE " + parameter.ParameterName + " AS " + parameter.SqlDbType.ToString() + " SET " + parameter.ParameterName + " = " + _parmStringValue;
                }                 
                else if (parameter.SqlDbType == SqlDbType.NVarChar || parameter.SqlDbType == SqlDbType.Char)
                {
                    _varlenght = parameter.Value.ToString().Length.ToString();
                    _parmStringValue = "'" + parameter.Value.ToString() + "'";
                    _return += Environment.NewLine + "DECLARE " + parameter.ParameterName + " AS " + parameter.SqlDbType.ToString() + "(" + _varlenght + ") SET " + parameter.ParameterName + " = " + _parmStringValue;
                }
                else
                {
                    _return += Environment.NewLine + "DECLARE " + parameter.ParameterName + " AS " + parameter.SqlDbType.ToString() + " SET " + parameter.ParameterName + " = " + parameter.Value.ToString();
                }


            }

            return "<div><pre><code class='language-sql'>" + _return + Environment.NewLine + Environment.NewLine + query + "</code></pre></div>";

        }