Кроме инструкции SELECT, которая была рассмотрена ранее, язык манипуляции данными DML (Data Manipulation Language) содержит три другие инструкции: INSERT, UPDATE и DELETE. Подобно инструкции SELECT эти три инструкции оперируют либо таблицами, либо представлениями. В этой статье рассматривается инструкция INSERT, а две другие инструкции рассматриваются в следующей статье.
Инструкция INSERT вставляет строки (или части строк) в таблицу. Существует две разные формы этой инструкции:
INSERT tab_name [(col_list)] DEFAULT VALUES | VALUES ({ DEFAULT | NULL | expression } [ ,...n]) INSERT INTO tab_name | view_name [(col_list)] {select_statement | execute_statement} Соглашения по синтаксису
Первая форма инструкции позволяет вставить в таблицу одну строку (или часть ее). А вторая форма инструкции INSERT позволяет вставить в таблицу результирующий набор инструкции SELECT или хранимой процедуры, выполняемой посредством инструкции EXECUTE. Хранимая процедура должна возвращать данные для вставки в таблицу. Применяемая с инструкцией INSERT инструкция SELECT может выбирать значения из другой или той же самой таблицы, в которую вставляются данные, при условии совместимости типов данных соответствующих столбцов.
Для обеих форм тип данных каждого вставляемого значения должен быть совместимым с типом данных соответствующего столбца таблицы. Все строковые и временные данные должны быть заключены в кавычки; численные значения заключать в кавычки не требуется.
Вставка одной строки
Для обеих форм инструкции INSERT явное указание списка столбцов не является обязательным. Отсутствие списка столбцов равнозначно указанию всех столбцов таблицы.
Параметр DEFAULT VALUES вставляет значения по умолчанию для всех столбцов. В столбцы с типом данных TIMESTAMP или свойством IDENTITY по умолчанию вставляются значения, автоматически создаваемые системой. Для столбцов других типов данных вставляется соответствующее ненулевое значение по умолчанию, если таково имеется, или NULL в противном случае. Если для столбца значения NULL не разрешены и для него не определено значение по умолчанию, выполнение инструкции INSERT завершается ошибкой и выводится соответствующее сообщение.
В примере ниже показана вставка строк в таблицу Employee базы данных SampleDb, демонстрируя использование инструкции INSERT для вставки небольшого объема данных в базу данных:
USE SampleDb; INSERT INTO Employee VALUES (34990, "Андрей", "Батонов", "d1"); INSERT INTO Employee VALUES (38640, "Алексей", "Васин", "d3");
Существует два разных способа вставки значений в новую строку. Инструкция INSERT в примере ниже явно использует ключевое слово NULL и вставляет значение NULL в соответствующий столбец:
USE SampleDb; INSERT INTO Employee VALUES (34991, "Андрей", "Батонов", NULL);
Чтобы вставить значения в некоторые (но не во все) столбцы таблицы, обычно необходимо явно указать эти столбцы. Не указанные столбцы должны или разрешать значения NULL, или для них должно быть определено значение по умолчанию.
USE SampleDb; INSERT INTO Employee(Id, FirstName, LastName) VALUES (34992, "Андрей", "Батонов");
Предыдущие два примера равнозначны. В таблице Employee единственным столбцом, разрешающим значения NULL, является столбец DepartmentNumber, а для всех прочих столбцов это значение было запрещено предложением NOT NULL в инструкции CREATE TABLE.
Порядок значений в предложении VALUES инструкции INSERT может отличаться от порядка, указанного в инструкции CREATE TABLE. В таком случае их порядок должен совпадать с порядком, в котором соответствующие столбцы перечислены в списке столбцов. Ниже показан пример вставки данных в порядке, отличающемся от исходного:
USE SampleDb; INSERT INTO Employee(DepartamentNumber, LastName, Id, FirstName) VALUES ("d1", "Батонов", 34993, "Андрей");
Вставка нескольких строк
Вторая форма инструкции INSERT вставляет в таблицу одну или несколько строк, выбранных подзапросом. В примере ниже показана вставка строк в таблицу, используя вторую форму инструкции INSERT. В данном случае выполняется запрос по выборке номеров и имен отделов, расположенных в Москве, и загрузка полученного результирующего набора в новую таблицу, созданную ранее.
Создаваемая в примере выше новая таблица MoscowDepartment имеет те же столбцы, что и существующая таблица Department, за исключением отсутствующего столбца Location. Подзапрос в инструкции INSERT выбирает в таблице Department все строки, для которых значение столбца Location равно "Москва", которые затем вставляются в созданную в начале запроса новую таблицу.
В примере ниже показан еще один способ вставки строк в таблицу, используя вторую форму инструкции INSERT. В данном случае выполняется запрос на выборку табельных номеров, номеров проектов и дат начала работы над проектом для всех сотрудников с должностью "Менеджер", которые работают над проектом p2 с последующей загрузкой полученного результирующего набора в новую таблицу, создаваемую в начале запроса:
USE SampleDb; CREATE TABLE ManagerTeam (EmpId INT NOT NULL, ProjectNumber CHAR (4) NOT NULL, EnterDate DATE); INSERT INTO ManagerTeam (EmpId, ProjectNumber, EnterDate) SELECT EmpId, ProjectNumber, EnterDate FROM Works_on WHERE Job = "Менеджер";
Перед вставкой строк с помощью инструкции INSERT таблицы MoscowDepartment и ManagerTeam (в примерах выше) были пустыми. Если же таблица уже существовала и содержала строки с данными, то к ней были бы добавлены новые строки.
Общий синтаксис:
а) вставка одной новой строки в таблицу:
INSERT <таблица> [(столбцы)]
VALUES (значения)
б) Вставка в таблицу одной или более строк, взятых из источника, указанного в подзапросе:
INSERT <таблица> [(столбцы)]
Правила:
Количество элементов в разделе «Столбцы» должно совпадать с количеством элементов в разделе «Значения»; типы данных должны совпадать либо допускать неявное преобразование;
В случае, когда раздел «Столбцы» отсутствует, раздел «Значения» должен содержать столько же значений, сколько всего столбцов в редактируемой таблице, кроме того, значения должны перечисляться в том же порядке, в каком объявлены столбцы таблицы; поэтому рекомендуется всегда явно указывать список столбцов, в которые будут добавляться новые значения;
В случае использования синтаксиса (б) подзапрос SELECT может быть адресован либо к этой же таблице, либо к другой таблице базы данных, либо к другой базе данных на сервере;
Если для некоторого столбца таблицы задано значение по умолчанию, и требуется в добавляемой записи использовать именно это значение, то в разделе «Значения» для этого столбца необходимо написать ключевое слово DEFAULT.
Примеры :
INSERT INTO detail (detail_name)
VALUES ("Подшипник")
INSERT INTO supply (supplier_id, supply_quantity, supply_cost,
supply_date, detail_id)
VALUES (4, 177, 453.45, "25.09.2009", 1)
INSERT supplier (supplier_type, supplier_name)
VALUES (DEFAULT, "Смирнов С. С.")
Модификация существующих записей (update)
Общий синтаксис:
UPDATE <таблица>
SET <столбец> = <значение> [, <столбец> = <значение>]
Примеры :
SET weight = 210
SET material_name = "Олово"
WHERE material_id = 2
SET department_id = NULL,
delivery_date = delivery_date + 1 /*увеличение даты поставки на день
WHERE delivery_id = 1 OR department_id > 3
SET detail_name = detail_name + "!!!"
WHERE detail_name LIKE "_а%" AND weight BETWEEN 6 AND 10
Удаление записей из таблицы (delete)
Общий синтаксис:
DELETE<таблица>
<условие>
Примеры :
WHERE detail_id IN (2, 5, 8)
WHERE weight IS NULL
Задание:
Заполните базу данных средствами ManagementStudio. Для этого следует воспользоваться командой «Открыть таблицу» контекстного меню таблицы в «Обозревателе объектов» (рис. 4.1).
Запросы на выборку данных
Общий синтаксис запроса select
SELECT <список столбцов>
FROM <таблица(-ы) источник>
Разделы SELECT и FROM обязательно должны присутствовать в каждом запросе; остальные разделы могут отсутствовать или присутствовать частично.
Примеры реализации запросов
Наиболее простые запросы:
1. Выбрать название и вес деталей
Рис. 5.1. Результаты выполнения запроса №1
2. Выбрать всю информацию из таблицы материалов
Рис. 5.2. Результаты выполнения запроса №2
Уникальность DISTINCT
3. Выбрать уникальные коды поставщиков из таблицы поставок
Рис. 5.3. Результаты выполнения запроса №3
Ограничение WHERE
4. Выбрать количество и даты поставки детали с кодом 1
Рис. 5.4. Результаты выполнения запроса №4
5. Выбрать названия поставщиков с кодами 1, 4 и 6
Рис. 5.5. Результаты выполнения запроса №5
6. Выбрать всю информацию о поставках, сделанных до 1.10.2009
Рис. 5.6. Результаты выполнения запроса №6
7. Выбрать всю информацию о деталях, не начинающихся на букву «В» (в любом регистре) и чей вес меньше 50
Рис. 5.7. Результаты выполнения запроса №7
8. Выбрать название и код материала для деталей с весом от 5 до 10 г или имеющих в названии букву «н» в третьей позиции
Рис. 5.8. Результаты выполнения запроса №8
9. Выбрать названия поставщиков длиной не больше 15-и символов
Рис. 5.9. Результаты выполнения запроса №9
10. Выбрать месяца и годы поставок деталей
Рис. 5.10. Результаты выполнения запроса №10
Сортировка ORDER BY
11. Упорядочить поставки сначала по коду поставщика, а затем по дате поставки
Рис. 5.11. Результаты выполнения запроса №11
12. Выбрать названия поставщиков с кодами 4, 6, 8, 9, упорядоченных по алфавиту в обратном порядке
Рис. 5.12. Результаты выполнения запроса №12
Агрегация и группировка GROUP BY
Рис. 5.13. Результаты выполнения запроса №13
14. Определить средний вес деталей из материала с кодом 2
Рис. 5.14. Результаты выполнения запроса №2
15. Из поставок, совершенных до 1.10.2009, выбрать самую крупную поставку и самую мелкую
Рис. 5.15. Результаты выполнения запроса №15
16. Для поставщиков с кодами в диапазоне 5 - 8 посчитать суммарное количество поставленных ими деталей
Рис. 5.16. Результаты выполнения запроса №16
Рис. 5.17. Результаты выполнения запроса №17
Ограничение на группировки HAVING
18. Выбрать материалы, для которых суммарный вес выполненных из них деталей не больше 20
Рис. 5.18. Результаты выполнения запроса №18
19. Из поставок 2008-го года выбрать детали, поставлявшиеся более одного раза
Рис. 5.19. Результаты выполнения запроса №19
Преобразование типов CAST
20. Получить сведения о датах поставок в текстовом виде
Рис. 5.20. Результаты выполнения запроса №20
21. Получить сведения из таблицы деталей в виде строк «Деталь X имеет вес Y»
Рис. 5.21. Результаты выполнения запроса №21
Альтернативы CASE
22. Разделить детали на легкие (весом до 20), средние (между 20 и 50) и тяжелые
Рис. 5.22. Результаты выполнения запроса №22
Обработка NULL-значений
23. Получить сведения о деталях и их весах, причем если у детали вес не задан, то вместо NULL написать -100
Рис. 5.23. Результаты выполнения запроса №23
Функция существования EXISTS
24. Выбрать название и код материала только тех деталей, которые когда-либо поставлялись
Рис. 5.24. Результаты выполнения запроса №24
25. Выбрать названия тех материалов, из которых не изготовлена ни одна деталь
Рис. 5.25. Результаты выполнения запроса №25
Подзапросы
26. Получить сведения о самой последней (по дате) поставке
Рис. 5.26. Результаты выполнения запроса №26
27. Получить все поставки деталей из материала с кодом 2
Рис. 5.27. Результаты выполнения запроса №27
28. Для каждого поставщика получить сведения о самой первой (по дате) его поставке
Рис. 5.28. Результаты выполнения запроса №28
29. Для каждого поставщика получить его имя и дату последнего заказа
Рис. 5.29. Результаты выполнения запроса №29
Объединение таблиц JOIN
30. Получить таблицу вида: название детали, название материала, из которого выполнена эта деталь
Рис. 5.30. Результаты выполнения запроса №30
31. Получить таблицу вида: поставщик, название детали, количество и дата поставки для деталей, у которых задан вес
Рис. 5.31. Результаты выполнения запроса №31
32. Выбрать всю информацию о тех деталях, которые когда-либо поставлялись
Рис. 5.32. Результаты выполнения запроса №32
Рис. 5.33. Результаты выполнения запроса №33
34. Выбрать названия материалов и сделанных из них деталей
Рис. 5.34. Результаты выполнения запроса №34
35. Получить все данные о поставщиках, поставках и деталях
Рис. 5.35. Результаты выполнения запроса №35
Объединение таблиц UNION
36. Получить таблицу названий и весов деталей, причем последняя строка таблицы должна содержать итоги в виде суммарного веса всех деталей
Рис. 5.36. Результаты выполнения запроса №36
37. Получить таблицу из двух полей, где первое поле – название детали, материала, поставщика или дата поставки, а второе поле – длина строки из первого поля
Рис. 5.37. Результаты выполнения запроса №37
Запросы на изменение используются для добавления (INSERT INTO), удаления (DELETE) и обновления (UPDATE) записей в таблицах.
Команда INSERT INTO
Команда INSERT INTO может быть использована для добавления одной или нескольких записей в конец таблицы.
Синтаксис команды INSERT INTO имеет следующий вид:
INSERT INTO Название_Таблицы [(Название_Полей)] VALUES (Значения_данных);
Например, поместим в таблицу "Группы" запись, содержащую данные (1, БФ-16а, 1, 1) в соответствующие столбцы (КодГруппы, Название, Курс, Семестр).
Для этого запрос в формате:
INSERT INTO Группы (КодГруппы, Название, Курс, Семестр) VALUES (1, БФ-16а, 1, 1);
введем на бланке запроса, выполнив команду "Конструктор запросов" на вкладке "Создание", в режиме "Режим SQL" из меню Вид.
Сохраняем запрос с именем "Добав_1_записи". В результате в «Области переходов» появится несвязанный объект - «Добав_1_записи» (Рис.1.).
Рис. 1.
После сохранения запроса необходимо выполнить этот запрос, щелкая на пиктограмме «Выполнить». В результате выполнения команды «Добав_1_записи» в пустой таблице появится первая запись (Рис. 2.)
Рис. 2.
Команда UPDATE
Команда UPDATE предназначена для изменения уже существующих записей в столбцах таблицы, что позволяет обновлять значения в заданных столбцах таблицы.
Синтаксис команды UPDATE имеет следующий вид:
UPDATE Название_Таблицы SET Название_Столбца = Новое_Значение WHERE Условие_Отбора;
В предложении SET указываются имена столбцов, данные в которых надо изменить. Оператор WHERE не является обязательным, но при его помощи можно указать только на те строки столбцов (таблиц), которые необходимо обновить.
Создадим запрос на изменение записи в таблице "Группы" базы данных sql_training_st.mdb.
Например, изменим уже существующую запись для первого ключевого поля id в столбце "Название" таблицы "Группы".
Запрос в формате:
UPDATE Группы SET Название ="БФ-16б" WHERE ID=1;
Сохраняем запрос с именем "Изменение_записи_1". В результате в «Области переходов» появится объект - «Изменение_записи_1» (Рис. 3.).
Рис. 3.
После сохранения запроса необходимо выполнить этот запрос, щелкая на пиктограмме «Выполнить». В результате выполнения команды «Изменение_записи_1» появится окно диалога, в котором необходимо ввести значение параметра ID=1 и нажать кнопку ОК. После этих действий в таблице "Группы" изменится запись в поле "Название" с БФ-16а на БФ-16б (Рис. 4.).
Рис. 4.
Команда DELETE
Команда DELETE предназначена для удаления записей из таблицы.
Формат запроса на удаление записей:
DELETE FROM Название_Таблицы WHERE Условие_Отбора;
Создадим запрос на изменение записи в таблице "Группы" базы данных sql_training_st.mdb.
Например, удалим существующую запись для первого ключевого поля id во всех столбцах (полях) таблицы "Группы".
Для этого запрос в формате:
DELETE FROM Группы WHERE ID=1;
создаем на бланке запроса, выполнив команду "Конструктор запросов" на вкладке "Создание", в режиме "Режим SQL" из меню Вид.
Сохраняем запрос с именем "Удаление_записи_1". В результате в «Области переходов» появится объект - «Удаление_записи_1» (Рис. 5.).
Рис. 5.
После сохранения запроса необходимо выполнить этот запрос, щелкая на пиктограмме «Выполнить». В результате выполнения команды «Удаление_записи_1» появится окно диалога, в котором необходимо ввести значение параметра ID=1 и нажать кнопку ОК. После этих действий откроется окно диалога "Подтвердите удаление записей". После подтверждения в таблице "Группы" будет удалены данные во всех полях, т.е. удалена запись (Рис. 6.).
Рис. 6.
Следует отметить, что для удаления данных в конкретных полях таблицы целесообразно воспользоваться командой UPDATE и заменить значения в требуемых полях на Null. Если необходимо удалить таблицу в целом, то следует использовать оператор DROP TABLE (синтаксис оператора: DROP TABLE Название_Таблицы;).
Восстановим первую запись в таблице "Группы", выполнив команду «Добав_1_записи», в результате восстановим первую запись (Рис. 7.).
Рис. 7.
Последнее обновление: 13.07.2017
Для добавления данных применяется команда INSERT , которая имеет следующий формальный синтаксис:
INSERT имя_таблицы [(список_столбцов)] VALUES (значение1, значение2, ... значениеN)
Вначале идет выражение INSERT INTO , затем в скобках можно указать список столбцов через запятую, в которые надо добавлять данные, и в конце после слова VALUES скобках перечисляют добавляемые для столбцов значения.
Например, пусть ранее была создана следующая база данных:
CREATE DATABASE productsdb; GO USE productsdb; CREATE TABLE Products (Id INT IDENTITY PRIMARY KEY, ProductName NVARCHAR(30) NOT NULL, Manufacturer NVARCHAR(20) NOT NULL, ProductCount INT DEFAULT 0, Price MONEY NOT NULL)
Добавим в нее одну строку с помощью команды INSERT:
INSERT Products VALUES ("iPhone 7", "Apple", 5, 52000)
После удачного выполнения в SQL Server Management Studio в поле сообщений должно появиться сообщение "1 row(s) affected":
Стоит учитывать, что значения для столбцов в скобках после ключевого слова VALUES передаются по порядку их объявления. Например, в выражении CREATE TABLE выше можно увидеть, что первым столбцом идет Id. Но так как для него задан атрибут IDENTITY, то значение этого столбца автоматически генерируется, и его можно не указывать. Второй столбец представляет ProductName, поэтому первое значение - строка "iPhone 7" будет передано именно этому столбцу. Второе значение - строка "Apple" будет передана третьему столбцу Manufacturer и так далее. То есть значения передаются столбцам следующим образом:
ProductName: "iPhone 7"
Manufacturer: "Apple"
Также при вводе значений можно указать непосредственные столбцы, в которые будут добавляться значения:
INSERT INTO Products (ProductName, Price, Manufacturer) VALUES ("iPhone 6S", 41000, "Apple")
Здесь значение указывается только для трех столбцов. Причем теперь значения передаются в порядке следования столбцов:
ProductName: "iPhone 6S"
Manufacturer: "Apple"
Для неуказанных столбцов (в данном случае ProductCount) будет добавляться значение по умолчанию, если задан атрибут DEFAULT, или значение NULL. При этом неуказанные столбцы должны допускать значение NULL или иметь атрибут DEFAULT.
Также мы можем добавить сразу несколько строк:
INSERT INTO Products VALUES ("iPhone 6", "Apple", 3, 36000), ("Galaxy S8", "Samsung", 2, 46000), ("Galaxy S8 Plus", "Samsung", 1, 56000)
В данном случае в таблицу будут добавлены три строки.
Также при добавлении мы можем указать, чтобы для столбца использовалось значение по умолчанию с помощью ключевого слова DEFAULT или значение NULL:
INSERT INTO Products (ProductName, Manufacturer, ProductCount, Price) VALUES ("Mi6", "Xiaomi", DEFAULT, 28000)
В данном случае для столбца ProductCount будет использовано значение по умолчанию (если оно установлено, если его нет - то NULL).
Если все столбцы имеют атрибут DEFAULT, определяющий значение по умолчанию, или допускают значение NULL, то можно для всех столбцов вставить значения по умолчанию:
INSERT INTO Products DEFAULT VALUES
Но если брать таблицу Products, то подобная команда завершится с ошибкой, так как несколько полей не имеют атрибута DEFAULT и при этом не допускают значение NULL.
Временами у программистов возникает жгучее желание прочитать что-то из базы данных. Программисты становятся нервными и раздражительными, теряют сон и лихорадочно тыкают пальцами в клавиатуру. Ради всеобщего блага и мира во всем мире рассмотрим несложную работу с базой данных из C# с помощью ADO.NET и OLE DB. Хотя данный механизм поддерживает разные базы данных вроде Oracle, здесь и сейчас будем использовать MS SQL Server.
Две основных задачи при работе с базой данных
2. Выполнение sql-команды, что-то делающей на сервере (insert, update, delete, вызов функции или хранимой процедуры
3. Последовательное чтение из select-выборки строки за строкой. В основном используется в веб-приложениях, в настольных проще скачать сразу всю выборку в оперативную память, экономия от чтения только нужных строк незначительна.
4. Редкий случай. Автоматическое обновление таблицы в базе на основании изменений в DataTable (как правило редактируемой через визуальный интрфейс). В реальной жизни данные обычно читаются через сложный запрос с кучей join или представление, так что автоматическая синхронизация не подходит.
Основные классы, используемые для этих целей: OleDbConnection - соединение с базой, создаем со строкой, содержащей параметры соеднинения, открываем, закрываем, OleDbCommand - создаем с экземпляром соединения и sql-командой, если нужно просто выполнить update или получить единичное значение, то хватит этого класса, OleDbDataAdapter - создается с OleDbCommand, специализируется на разовом чтении наборов строк в DataTable, может автоматически создавать колонки DataTable на основании выборки, переносить изменения из DataTable в таблицу в базе, OleDbDataReader - последовательное чтение строк в DataTable по одной за раз (он работает внутри OleDbDataAdapter), DataTable / DataSet - основной контейнер для данных. В перечислении OleDbType хранятся типы данных базы данных.
Using System.Data; using System.Data.OleDb; // строка соединения, используется система пользователей Windows (Integrated Security=SSPI;) string connString = "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=databaseName;Data Source=serverName"; // альтернативная строка соединения с иcпользованием аутентификации MS SQL Server // connString = "Provider=SQLOLEDB.1;Persist Security Info=False;Initial Catalog=databaseName;Connect Timeout=20;Data Source=serverName;Uid=userName;Pwd=userPassword;" OleDbConnection dbConn = new OleDbConnection(connString); dbConn.Open(); someDataTable = new DataTable(); OleDbDataAdapter dbAdapter = new OleDbDataAdapter("select COLUMN1, COLUMN2 from TEST_TABLE ORDER BY COLUMN2", dbConn); // внутренняя структура пустой таблицы будет создана автоматически на основании прочитанных данных, если структура таблицы уже задана (например через типизированный DataSet), то данные будут писаться в столбцы с совпадающими именами или добавятся новые столбцы dbAdapter.Fill(someDataTable); // альтернативный вариант для заполнения таблицы в DataSet // dbAdapter.Fill(someDataSet, "someDataTable"); dbConn.Close();
2. Выполнение sql-команды, что-то делающей на сервере (insert, update, delete, вызов функции или хранимой процедуры .
Особенно стоить отметить проблемы с датами. Реализация дат в.Net крайне кривая - изначально даты не могут быть пустыми, а реальной жизни они пустые сплошь и рядом. Самое правильное решение - использовать специальный класс даты, исправляющий косяки программистов из Microsoft. Более ленивые разработчики держат все даты в коде строками и конвертируют их в DateTime только при необходимости, например при записи в базу или DataTable. Nullable DateTime не спасает, так как пустая дата в интерфейсе должна выглядеть пустой строкой, а при записи в базу как DBNull.Value - и банальный null в коде не конвертируется в эти значения без дополнительных плясок с бубном.
Первый вариант подразумевает банальное склеивание строки запроса. Считается плохой практикой и особенно опасен в веб-приложениях, так как уязвим для хакерских атак. Проблема с пустыми датами так просто не решается. Кроме того при работе с датами появляется дополнительная проблема - разные форматы строк даты в зависимости от региональный настроек.Net Framework, среды разработки и sql-сервера. Выглядеть это может сюрреалистически - один и тот же запрос работает в SQL Managment Studio, но вылетает при выполнении из кода. Частично спасает особый формат строки дат, Тем не менее так нередко делают в маленьких программках для внутреннего пользования, о существовании которых внешний мир никогда не узнает.
OleDbCommand dbCommand = dbConn.CreateCommand(); dbCommand.CommandText = "INSERT INTO TEST_TABLE (INT_COLUMN, VARCHAR_COLUMN, DATETIME_COLUMN) VALUES (" + intVariable", " + stringVariable" , " + dateTimeVariable.ToString("yyyyMMdd") +")"; dbCommand.ExecuteNonQuery();
Правильный вариант подразумевает создание команды с набором строго типизированных параметров. Считайте, что предыдущего абзаца не было.
OleDbCommand dbCommand = dbConn.CreateCommand(); dbCommand.CommandText = "INSERT INTO TEST_TABLE (INT_COLUMN, VARCHAR_COLUMN, DATETIME_COLUMN) VALUES (?, ?, ?)"; dbCommand.Parameters.Add("INT_COLUMN", OleDbType.Integer).Value = intVariable; dbCommand.Parameters.Add("VARCHAR_COLUMN", OleDbType.VarChar).Value = stringVariable; if (stringDate == "") { dbCommand.Parameters.Add("DATETIME_COLUMN", OleDbType.DateTime).Value =DBNull.Value; } else { dbCommand.Parameters.Add("DATETIME_COLUMN", OleDbType.DateTime).Value = Convert.ToDateTime(stringDate); } dbCommand.ExecuteNonQuery();
Хранимая процедура вызывается точно так же, разнообразия ради другой вариант записи значений в параметры (он не связан именно с хранимой процедурой):
OleDbCommand someDbComm = new OleDbCommand("someStoredProcedure", this.dbConn); someDbComm.CommandType = CommandType.StoredProcedure; someDbComm.Parameters.Add("@parameter1", OleDbType.VarChar); someDbComm.Parameters.Add("@parameter2", OleDbType.VarChar); someDbComm.Parameters.Value = "У всякой проблемы всегда есть решение - простое, удобное и, конечно, ошибочное"; someDbComm.Parameters.Value = "Генри Луис Менкен"; someDbComm.ExecuteNonQuery();
Расширенный вариант описания параметра с указанием размера поля и привязкой к конкретной колонке таблицы.
DbCommand.Parameters.Add("VARCHAR_COLUMN", OleDbType.VarChar, 100, "VARCHAR_COLUMN").Value = stringVariable;
Если нам не нужна привязка параметра команды к определенному полю DataTable, то лучше всего не указывать размер вообще, так например если строка будет меньше указанной длинны Varchar, то добрый.Net фреймворк добавит в строку пробелов до указанной длины, испортив передаваемые на сервер данные.
Значение единичного поля читается методом ExecuteScalar()
OleDbCommand dbCommand = dbConn.CreateCommand(); dbCommand.CommandText = "SELECT TEST_COLUMN FROM TEST_TABLE WHERE ID_COLUMN = ?"; dbCommand.Parameters.Add("INT_COLUMN", OleDbType.Integer).Value = intVariable; int result = Convert.ToInt32(dbCommand.ExecuteScalar());
Надо особо отметить, что ExecuteScalar возвращает Object и если запрос не вернул вообще ничего, то результат будет null и конвертация в нормальный тип данных вылетит с ошибкой. Если возможна ситуация, когда в ответ мы ничего не получим, то надо делать так:
OleDbCommand dbCommand = dbConn.CreateCommand(); dbCommand.CommandText = "SELECT TEST_COLUMN FROM TEST_TABLE WHERE ID_COLUMN = ?"; dbCommand.Parameters.Add("INT_COLUMN", OleDbType.Integer).Value = intVariable; object resultObj = dbCommand.ExecuteScalar() int result = -1; // значение по умолчанию, означающее пустой результат if(resultObj != null) { result = Convert.ToInt32(dbCommand.ExecuteScalar()); }
3. Последовательное чтение из select-выборки строки за строкой
Чтение одной строки (несколько читаются в цикле);
OleDbCommand dbCommand = new OleDbCommand(select PERSON_ID, NAME, SURNAME from TEST_TABLE, dbConn); OleDbDataReader dbReader = dbCommand.ExecuteReader(); dbReader.Read(); string name = Convert.ToString(dbReader["NAME"]); string surname = Convert.ToString(dbReader["SURNAME"]); dbReader.Close();
4. Редкий случай. Автоматическое обновление таблицы в базе на основании изменений в DataTable (как правило редактируемой через визуальный интерфейс).
Необходимо прописать для DbAdapter четыре команды на каждый возможный случай - select, insert, update, delete.
DbAdapter.InsertCommand = new OleDbCommand("insert into TEST_TABLE (NAME, FAMIL, AGE) values (?, ?, ?)", dbConnection); dbAdapter.InsertCommand.Parameters.Add("NAME", OleDbType.VarChar, 100, "NAME"); dbAdapter.InsertCommand.Parameters.Add("FAMIL", OleDbType.VarChar, 100, "FAMIL"); // для типов данных с неизменной длинной указанная в команде длинна игнорируется dbAdapter.InsertCommand.Parameters.Add("AGE", OleDbType.Integer, 100, "AGE"); // добавляем команду обновления dbAdapter.UpdateCommand = new OleDbCommand("update TEST_TABLE set NAME = ?, FAMIL = ?, AGE = ? where ID = ?", dbConnection); dbAdapter.UpdateCommand.Parameters.Add("NAME", OleDbType.VarChar,100, "NAME"); dbAdapter.UpdateCommand.Parameters.Add("FAMIL", OleDbType.VarChar, 100, "FAMIL"); dbAdapter.UpdateCommand.Parameters.Add("AGE", OleDbType.Integer, 100, "AGE"); dbAdapter.UpdateCommand.Parameters.Add("ID", OleDbType.Integer, 100, "ID"); // добавляем команду удаления dbAdapter.DeleteCommand = new OleDbCommand("delete from TEST_TABLE where ID = ?", dbConnection); dbAdapter.DeleteCommand.Parameters.Add("ID", OleDbType.Integer, 100, "ID"); try { // переносит все изменения из DataTable в таблицу в базе данных dbAdapter.Update(table); } catch (Exception error) { MessageBox.Show("Ошибка при сохранении данных! " + error.Message); return; } MessageBox.Show("Изменения сохранены!");