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

#c# #.net #mysql #parameterized

#c# #.net #mysql #параметризованный

Вопрос:

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

 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();
  

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

Ответ №1:

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

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

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

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

Комментарии:

1. Для MS SQL иерархией наследования класса ‘SqlParameter’ является System.Data.SqlClient.SqlParameter. Для MySQL это будет MySQL.Data.MySqlClient . MySqlParameter

2. Если вы это сделаете. AddWithValue(«@P1», …) тогда ParameterName уже начинается с «@», поэтому приведенный выше код пытается заменить «@@P1» значением, поэтому он не работает. Чего мне не хватает?

3. Я знаю, что это устарело, но в вашем коде есть проблемы. Прежде всего, вы используете command в первой строке и cmd в других. Они должны быть одинаковыми. Во-вторых, нет необходимости вызывать ToString() on CommandText . Это уже строка. Далее, параметр должен быть заключен в кавычки, только если это заключаемое в кавычки значение. Например, целые числа не являются. И, наконец, как уже указывалось, вы не должны добавлять @ к имени параметра, поскольку оно обычно уже есть.

Ответ №2:

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

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

Комментарии:

1. Ах, хорошо, я не знал об этом. Я думал, что параметры и значения были объединены в библиотеке MySQL перед отправкой на сервер, урок усвоен.

2. @Mike: Возможно , что они есть, но, конечно, не обязательно , и лично я надеюсь, что это не так 🙂

Ответ №3:

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

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

Комментарии:

1. Спасибо за ваш ответ. Я не знал, что значения остаются отдельными на всем пути до сервера.

Ответ №4:

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

Комментарии:

1. Это для отладки, по сути, у меня есть запрос, который не приводит к тому, что я ожидаю. Я надеялся просто взять «окончательный» запрос из приложения и сверить его с базой данных, думаю, мне придется сделать это таким образом. Спасибо за ваш ответ.

Ответ №5:

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

Ответ №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 resu<
    }
  

Ответ №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>";

        }
  

Ответ №8:

Для тех, кто хочет использовать ответ Кристофера с Mysql, это сработало для меня…

 string tmp = cmd.CommandText.ToString();
foreach (MySqlParameter param in cmd.Parameters)
{
    tmp = tmp.Replace(param.ParameterName.ToString(), "'"   param.Value.ToString()   "'");
}