Модераторы: gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как правильно написать Insert? 
V
    Опции темы
avlzll
Дата 16.12.2009, 01:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 43
Регистрация: 30.11.2007

Репутация: нет
Всего: нет



Приветствую.

Недавно начал разбираться с C# и возник вопрос, как правильно INSERT писать? Попинал Google немного и в результате накатал вот чего:

Вкратце суть в том, что надо собрать кучу введенных значений (в данном случае об автомобиле) с разных контролов и вотнуть их [значения] в БД.

Код

string queryString = 
                " INSERT INTO car" +
                "(carRegNum, carVIN, carMark, carClass, carSeatsNum, carEngCap, carFuelType, carYear, carRateValue, insRegNum, techInsPassNum)" +
                " VALUES" +
                "(@carRegNum, @carVIN, @carMark, @carClass, @carSeatsNum, @carEngCap, @carFuelType, @carYear, @carRateValue, @insRegNum, @techInsPassNum)";

            using (MySqlConnection connection = new MySqlConnection(GetConnectionString()))
            {
                try
                {
                    connection.Open();
                    MySqlCommand cmd = new MySqlCommand(queryString, connection);
                    MySqlParameter[] param = new MySqlParameter[11];

                    param[0] = new MySqlParameter("@carRegNum", MySqlDbType.VarChar);
                    param[1] = new MySqlParameter("@carVIN", MySqlDbType.Int32);
                    param[2] = new MySqlParameter("@carMark", MySqlDbType.VarChar);
                    param[3] = new MySqlParameter("@carClass", MySqlDbType.VarChar);
                    param[4] = new MySqlParameter("@carSeatsNum", MySqlDbType.Int32);
                    param[5] = new MySqlParameter("@carEngCap", MySqlDbType.Int32);
                    param[6] = new MySqlParameter("@carFuelType", MySqlDbType.VarChar);
                    param[7] = new MySqlParameter("@carYear", MySqlDbType.Int32);
                    param[8] = new MySqlParameter("@carRateValue", MySqlDbType.Int32);
                    param[9] = new MySqlParameter("@insRegNum", MySqlDbType.Int32);
                    param[10] = new MySqlParameter("@techInsPassNum", MySqlDbType.Int32);

                    param[0].Value = textBox1.Text;
                    param[1].Value = textBox3.Text;
                    param[2].Value = textBox2.Text;
                    param[3].Value = comboBox2.SelectedText;
                    param[4].Value = comboBox5.SelectedText;
                    param[5].Value = textBox4.Text;
                    param[6].Value = comboBox6.SelectedText;
                    param[7].Value = textBox6.Text;
                    param[8].Value = textBox5.Text; 
                    param[9].Value = comboBox3.SelectedText;
                    param[10].Value = comboBox4.SelectedText;

                    for (int i = 0; i < param.Length; i++)
                    {
                        cmd.Parameters.Add(param[i]);
                    }

                    cmd.CommandType = CommandType.Text;
                    cmd.ExecuteNonQuery();

                }


Выглядит немного монструозно, на мой взгляд.

Скажем, так написать можно? Будет ли это правильно/безопасно/[...] ?

Код

string queryString = "INSERT INTO car (carRegNum) VALUES (TextBox1.Text)";


Это сообщение отредактировал(а) avlzll - 16.12.2009, 01:33
PM MAIL   Вверх
mrbrooks
Дата 16.12.2009, 09:38 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 5
Всего: 306



Цитата(avlzll @  16.12.2009,  01:33 Найти цитируемый пост)
Выглядит немного монструозно, на мой взгляд.

есть такое. К примеру можно и так:
Код

using (MySqlConnection connection = new MySqlConnection(GetConnectionString()))
            {
                    connection.Open();
                    MySqlCommand cmd = connection.CreateCommand();

                    cms.Parameters.AddWithValue("@carRegNum", textBox1.Text);
                    cms.Parameters.AddWithValue("@carVIN", textBox3.Text);
                    //...
                    cms.Parameters.AddWithValue("@techInsPassNum", comboBox4.SelectedText);
                    cmd.ExecuteNonQuery();
                }


но это не принципиально. так же не обязательно заполнять циклом cmd.Parameters.Add() - для этого есть метод cmd.Parameters.AddRange().


Цитата(avlzll @  16.12.2009,  01:33 Найти цитируемый пост)
Скажем, так написать можно? Будет ли это правильно/безопасно/

Можно. Только:
во первых, не забывай, что ты работаешь со строками - поэтому твой код со строкой работать не будет.
во вторых - надо будет учитывать типы данных используемой СУБД (для строк использовать кавычки и т.д.)
Очевидно - параметры помогают обойти все эти нюансы.

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

PM MAIL   Вверх
advantiss1
Дата 16.12.2009, 19:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 16.12.2009

Репутация: нет
Всего: нет



Цитата(avlzll @  16.12.2009,  01:33 Найти цитируемый пост)
Скажем, так написать можно? Будет ли это правильно/безопасно/[...] ?


Это неправильно и небезопасно. Насчет неправильно ответил mrbooks, насчет небезопасно - почитай про атаки "SQL Injection".

Цитата(mrbrooks @  16.12.2009,  09:38 Найти цитируемый пост)
Вообще на будущее, любое изменение значений БД рекомендуется реализовывать в виде хранимых процедур.


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


Это сообщение отредактировал(а) advantiss1 - 16.12.2009, 20:32
PM MAIL   Вверх
mrbrooks
Дата 17.12.2009, 09:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 5
Всего: 306



Цитата(advantiss1 @  16.12.2009,  19:14 Найти цитируемый пост)
Если правильно разделять логику и данные, то лучше от процедур отказаться где это возможно... исключениями могут быть случаи где использование процедур значительно повысит быстродействие запроса(групповые обработки записей например).

На самом деле это как с хранением картинок в БД. Можно и ссылкой, и файлом. Хранимая процедура - из этой же оперы. Кому то проще ее использовать, кому то нет. Одни считаю - пусть все делает сервер, другие - клиент.
PM MAIL   Вверх
advantiss1
Дата 17.12.2009, 11:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 16.12.2009

Репутация: нет
Всего: нет



Цитата(mrbrooks @  17.12.2009,  09:20 Найти цитируемый пост)
На самом деле это как с хранением картинок в БД. Можно и ссылкой, и файлом. Хранимая процедура - из этой же оперы. Кому то проще ее использовать, кому то нет. Одни считаю - пусть все делает сервер, другие - клиент.



Цитата из оригинальной статьи
Цитата

Сказка вторая. «Бизнес-логика»

Мне постоянно попадаются апологеты подхода «Все в базу». Суть подхода заключается в том, что БД используют не только по прямому назначению, а именно: размещение структурированых данных, их выборка и модификация, но и с целью агрессивного внедрения бизнес-логики в рамки БД. Последнее связывает данные и логику в рамках одной СУБД — это словно закупорить джина в бутылку, и ждать момента, когда он вырвется на свободу круша и ломая все вокруг. Течение, связанное с интеграцией бизнес-логики в БД, появилось в середине 90-х, когда потребовался многочисленный рефакторинг3 ПО.

Чтобы не быть голословным, приведу основные доводы в пользу подхода «Все в базу»:

   1. Безопасность. Считается, что значительно надежнее дать права на хранимую процедуру и защитить логику обработки данных, чем дать права на таблицы и затем пытаться реализовать сохранность данных с помощью триггеров.
   2. Скорость. Выполнение хранимых процедур происходит в адресном пространстве СУБД, что означает близость к хранимым данным, что в свою очередь, уменьшает время реакции системы.
   3. Специализация языков для разработки хранимых процедур. Такие языки «заточены» на работу с данными в БД, что опять же положительно сказывается на скорости работы ХП.
   4. Локализация изменений. Изменение логики работы системы производится в единственном месте, и в большинстве случаев не требует перекомпиляции клиентского ПО и последующей его переинсталяции.
   5. Минимизация трафика. Уменьшение объемов трафика связано с тем, что пользователю возвращается результат выполнения ХП, а не сырые данные.

Спорить с данными утверждения бессмысленно, так как они в основе своей истинны. Однако, если конкретизировать вопрос, а именно, нужно ли хранить бизнес-логику в БД при использовании трехзвенной архитектуры с выделением полноценного «сервера приложения»? Если для стартапа создание такой инфраструктуры не всегда оправданно, то для корпоративного применения практически нет альтернативных решений, — монстры индустрии, естественно, предлагают собственные решения для промежуточного слоя.

Исходя из вышесказанного, хочу напомнить одно из правил разработки приложений:

    «Самое главное — это концентрация бизнес логики на одном уровне. А выбор уровня зависит от конкретной задачи.»
    — Киселев Сергей, соучредитель и консультант по технологиям и разработке, ООО «Научно-производственная компания Ай-поинт рус».


Вынесение бизнес-логики на уровень БД — это концентрация ее в месте, где вы теряете контроль за производительностью, масштабированием и переносимостью и, в значительной степени, полагаетесь на производителя СУБД.

    «Если переносить логику приложения в БД, то привязываешь себя к конкретной БД, а что еще точнее и хуже, к конкретной версии СУБД. Теряется гибкость. В то же время, если мы понимаем, что такое кросс-платформенная реализация, то перенесение логики в рамках реализации куда бы то ни было не составляет никаких проблем. И как этим управлять вполне известно.»
    — Виктор Гамов, ведущий программист, учебно-научный центр МИИТ-Эксперт.


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

    «Такая логика вендор-специфик, трудно отлаживаемая, неподвластна рефакторингу, тестирование возможно лишь статическим анализом. Однако, наверняка найдется дюжина аргументов за бизнес-логику на стороне СУБД. В их числе может оказаться, например, погоня за производительностью или необходимость хитрого управления блокировками на строках таблиц БД. В этих случаях все перечисленные минусы становятся неприятным следствием компромисса. А разработчики, в свою очередь, становятся жертвами этих минусов.»
    — Гура Андрей, менеджер проекта, Яндекс.


Конечно, принимать решение о месте нахождения бизнес-логики при реализации следует исходя из поставленной задачи. Исходя из того, что одни и те же действия по обработке данных возможно реализовать как в хранимой процедуре непосредсвенно на уровне СУБД, так и в приложении.

    «Всю бизнес-логику условно можно разделить на «две части». Одна часть — «обслуживание данных», вторая «реализация прикладной задачи». Первую логичнее держать в СУБД, рядом с данными, вторую — на сервере приложений. Под «обслуживание данных» я понимаю поддержку непротиворечивости данных с точки зрения прикладной задачи и функции типа собрать из первичных данных прикладные-расчетные.»
    — Владимир Бормотов, системный админситратор, ЗАО «БиоХимМак».


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


Действительно, если речь идет о "карманном" приложении, разработка которого займет месяц, делать можно как душе пожелается. Но когда речь идет о масштабируемых системах, которые разрабатываются годами - содержание части бизнес логики в БД может в дальнейшем сыграть над разработчиками злую шутку... Сюда же можно отнести и продукты, которые имеют шанс стать массовыми.
PM MAIL   Вверх
thomas
Дата 17.12.2009, 11:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доцент... почти
***


Профиль
Группа: Завсегдатай
Сообщений: 1385
Регистрация: 3.10.2006
Где: " Сказочное королевство"

Репутация: 35
Всего: 65



advantiss1, 
Статья не плохая. Точка зрения имеет место быть. Но написал её java-разработчик.
Хоть в этом мире и есть много общего, но различия между java и .NET все же есть.



avlzll, 
Выскажу свое мнение, личное.
Я конечно не писал "корпоративные" программы, но несколько программ, которые активно работают с MS SQL server 2005, писал и принимал участие в написании.
Так вот что, я хочу сказать про хранимые процедуры. 
Вместо чистого написания SQL команд в коде приложения практически всегда использовали ХП. Только при работе с БД Access писали SQL команды с параметрами.
Я считаю что, вызов ХП из приложения и передача ей необходимых параметров корааздо удобнее и безопаснее чем использование построителя строки для формирования SQL команды.
Плюс ХП поддерживают выходные параметры + return. Что в свою очередь дает определенные преимущества. Например можно сразу получить ID для сохраненной строки в таблице БД.
А использование return позволяет организовать свою обработку исключений.

В так называемых трех-слойных моделях: слой доступа к данным, слой бизнес логики и слой представления 
никакого смещения бизнес логики приложения из второго слоя в БД не происходит.
В данном случае нижний слой можно реализовать для работы с БД на MS SQL server с использованием ХП, а можно его вообще переписать для работы с XML файлами, в которых будет храниться информация.
Два других слоя приложения об этом даже и знать не будут.
Центральный слой - бизнес логики, сам определяет какие данные ему нужны для работы, что с этими данными делать и что нужно сохранять в БД или другое "хранилице".
Слой представления тоже может быть реализован в двух вариантах: десктопное приложение или веб приложение. Как получаются и обрабатываются данные этому слою по барабану.
Он отвечает только за представление - вывод на экран. Ну и естественно за передачу вниз "действий" пользователя.

Так что все вполне изменяемо и маштабируемо (во завернул).
При переходе с одного хранилища данных на другое нужно переписать только одну dll(слой доступа к данным).
При смене типа приложения переписываем только слой представления.
Ну а при смене бизнес логики переписываем dll слоя бизнес логики.


ЗЫ да забыл упомянуть в дополнение к тому что сказал mrbrooks
Цитата

во первых, не забывай, что ты работаешь со строками - поэтому твой код со строкой работать не будет.
во вторых - надо будет учитывать типы данных используемой СУБД (для строк использовать кавычки и т.д.)
Очевидно - параметры помогают обойти все эти нюансы.

 при использовании ХП мы должны передать ей параметры. Так вот при передачи этих самых параметров мы можем легко проверить их на соответствие типу данных и привести к нужному питу.
Плюс выполнить проверку на DBNULL как при получении данных так и при их сохранении в БД. Ну не заполнил пользователь какое-то поле. Знасит мы должны сохранить в БД DBNULL, а при получении данных привести этот DBNULL к простому нулю (0) если это число или дефолтному строковому значению - <не указано>.
Это позволяет избежать исключений при выполнении SQL команд. Особые проблемы вызывают данные типа Datetime. С ХП с ними проблем нет. 

Это сообщение отредактировал(а) thomas - 17.12.2009, 12:04


--------------------
Крепко жму горло, искренне ваш Thomas. (С)vingrad
Некоторые сорта флоры буквально за одно мгновение превращают нас в фауну!
Проблемы негров шерифа не волнуют.
PM MAIL   Вверх
advantiss1
Дата 17.12.2009, 15:07 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 16.12.2009

Репутация: нет
Всего: нет



Цитата(thomas @  17.12.2009,  11:53 Найти цитируемый пост)
Статья не плохая. Точка зрения имеет место быть. Но написал её java-разработчик.
Хоть в этом мире и есть много общего, но различия между java и .NET все же есть.

я сам .NET девелопер, но в данном контесте абсолютно нет разницы какая среда программирования используется. Речь идет о правильном построении приложений с использованием n-звенной архитектуры

Цитата(thomas @  17.12.2009,  11:53 Найти цитируемый пост)
При переходе с одного хранилища данных на другое нужно переписать только одну dll(слой доступа к данным).

если речь идет о переходе с одного SQL движка на другой, то чем больше использовано ХП, нестандартных для SQL функций и других примочек - тем больше займет времени написание библиотеки под другой движок БД(а как всегда всё надо срочно и прямо сейчас)

PM MAIL   Вверх
mrbrooks
Дата 17.12.2009, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 5
Всего: 306



Цитата(advantiss1 @  17.12.2009,  15:07 Найти цитируемый пост)
если речь идет о переходе с одного SQL движка на другой, то чем больше использовано ХП, нестандартных для SQL функций и других примочек - тем больше займет времени написание библиотеки под другой движок БД(а как всегда всё надо срочно и прямо сейчас)

во. это уже действительно весомый аргумент. бесспорно не во всех СУБД есть ХП (хотя в ведущих они присутствуют). а это дополнительный гемморой.  smile 
PM MAIL   Вверх
thomas
Дата 17.12.2009, 16:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доцент... почти
***


Профиль
Группа: Завсегдатай
Сообщений: 1385
Регистрация: 3.10.2006
Где: " Сказочное королевство"

Репутация: 35
Всего: 65



advantiss1, 
Приветствую.
Поясню свое высказывание
Цитата

При переходе с одного хранилища данных на другое нужно переписать только одну dll(слой доступа к данным).


Под хранилищем данных, я здесь подразумеваю, либо ту или иную базу данных (MS SQL, MySQL, Oracle, ...), либо файловую систему (XML, Sequentiële  файлы, ...) 
Т.е. если по какой то причине клиенту вдруг вздумается  хранить свои данные не в БД, а в виде тех или иных файлов, то просто переписываем DAL на работу с файловой системой.  

А вот по поводу 
Цитата

если речь идет о переходе с одного SQL движка на другой, то чем больше использовано ХП, нестандартных для SQL функций и других примочек - тем больше займет времени написание библиотеки под другой движок БД(а как всегда всё надо срочно и прямо сейчас)

могу сказать следующее:
в серьезных конторах при разработке серьезных проектов разработке ВСЕГДА предшествует АНАЛИЗ(да и в не очень серьезных тоже, тут по крайней мере).
Так вот во время анализа и определяется  какой будет система, как и где она будет хранить свои данные, как и какими она их будет обрабатывать, и как она будет взаимодействовать с пользователем.
После правильного АНАЛИЗА вероятность переезда с одной БД на другую маловероятна. Но даже в этом случае вместо переработки всего приложения нужно переписать только один DAL.
К тому же надо учесть и такой момент, что хранимые процедуры выполняют только стандартные действия (insert, select, update, delete), а вся бизнес логика "сидит" не в них, а BL.
И уж если вы переезжаете с одного типа БД на другой, то в любом случае нужно будет создавать новую БД. А в DAL переделать connection и возможно параметры для ХП. Названия ХП и таблиц логичнее сохранить. Если нет, то нет.

Вообще топик был про другое:
что лучше и безопаснее?
- писать SQL команды в коде;
- использовать ХП.

На этот вопрос ответ однозначный - лучше использовать ХП (мое мнение).



Это сообщение отредактировал(а) thomas - 17.12.2009, 16:32


--------------------
Крепко жму горло, искренне ваш Thomas. (С)vingrad
Некоторые сорта флоры буквально за одно мгновение превращают нас в фауну!
Проблемы негров шерифа не волнуют.
PM MAIL   Вверх
advantiss1
Дата 17.12.2009, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 16.12.2009

Репутация: нет
Всего: нет



Цитата(thomas @  17.12.2009,  16:30 Найти цитируемый пост)
На этот вопрос ответ однозначный - лучше использовать ХП (мое мнение).

"ответ однозначный" != "моё мнение"  smile 



Цитата(thomas @  17.12.2009,  16:30 Найти цитируемый пост)
Вообще топик был про другое:
что лучше и безопаснее?
- писать SQL команды в коде;
- использовать ХП.

В бизнес системах используется и тот и другой подходы, плюсы/минусы описаны выше.

Эдинственно неправильным в подходе автора топика есть передача параметров запроса с помощью подстановки строк
Цитата

    
Код

string queryString = "INSERT INTO car (carRegNum) VALUES (TextBox1.Text)";



Все остальное вполне усваиваемо smile
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
stab
mr.DUDA
Exception

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, stab, mr.DUDA, Exception.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Базы данных под .NET | Следующая тема »


 




[ Время генерации скрипта: 0.0536 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.