Как правильно написать запрос sql на добавление записи в таблицу БД? c# VS13 [закрыт]
Закрыт. Этот вопрос не по теме. Ответы на него в данный момент не принимаются.
Вопросы с просьбами помочь с отладкой («почему этот код не работает?») должны включать желаемое поведение, конкретную проблему или ошибку и минимальный код для её воспроизведения прямо в вопросе. Вопросы без явного описания проблемы бесполезны для остальных посетителей. См. Как создать минимальный, самодостаточный и воспроизводимый пример.
Закрыт 7 лет назад .

Мне нужно сохранить данные из textBox’ов в новою строку таблицы «Writers» моей БД. Я пытался сделать это так, но видимо где то накосячил, ошибок нет но таблица не изменяется!
Урок 1. Первые SQL запросы
Добро пожаловать на первый урок по реляционным базам данных и языку SQL.
Реляционные базы данных представляют собой набор таблиц с информацией.
Вроде такой:
| id | name | count | price |
|---|---|---|---|
| 1 | Телевизор | 3 | 43200.00 |
| 2 | Микроволновая печь | 4 | 3200.00 |
| 3 | Холодильник | 3 | 12000.00 |
| 4 | Роутер | 1 | 1340.00 |
| 5 | Компьютер | 0 | 26150.00 |
| id | first_name | last_name | birthday | age |
|---|---|---|---|---|
| 1 | Дмитрий | Иванов | 1996-12-11 | 20 |
| 2 | Олег | Лебедев | 2000-02-07 | 17 |
| 3 | Тимур | Шевченко | 1998-04-27 | 19 |
| 4 | Светлана | Иванова | 1993-08-06 | 23 |
| 5 | Олег | Ковалев | 2002-02-08 | 15 |
| 6 | Алексей | Иванов | 1993-08-05 | 23 |
| 7 | Алена | Процук | 1997-02-28 | 18 |
Каждая таблица состоит из столбцов и строк.
Посмотрим внимательней на таблицу products, которая хранит данные о товарах в интернет-магазине. Таблица содержит 4 столбца: id, name, count и price. Каждый из столбцов отвечает за какой-то определенный тип информации: id — это уникальный номер товара, name — его имя, count — количество, price — цена.
Строка отвечает за конкретный товар в таблице. Если мы посмотрим на третью строку, то найдем там «Холодильник» с ценой 12 000 рублей в количестве 3 штук.
Другая таблица — это users, которая хранит данные о пользователях в системе. В таблице 5 столбцов: также уникальный номер пользователя id, имя, фамилия, возраст — age и дата рождения — birthday.
Как я уже говорил, каждый столбец отвечает за какую-то информацию и эта информация относится к определенному типу данных. Столбцы first_name и last_name строковые, age и id содержат числа, а birthday — дату.
Название столбца, его тип и порядок строго задаются на этапе создания таблицы. Об этом мы поговорим в других уроках.
А вот записи таблицы (или строки) заполняются в процессе её использования. Поэтому столбцов у нас жестко 5. А строк может быть сколько угодно. Зарегистрировался пользователь на сайте — добавили строку. Привезли новые товары в магазин — таблица растет.
Добавление, удаление, изменение или получение данных из таблиц, выполняется с помощью языка SQL.
SQL — это язык общения с базами данных.
Давайте попробуем получить информацию из таблицы users. Для этого надо написать и выполнить такой SQL-запрос:
SELECT * FROM users
Получили всех пользователей из таблицы users:
| id | first_name | last_name | birthday | age |
|---|---|---|---|---|
| 1 | Дмитрий | Иванов | 1996-12-11 | 20 |
| 2 | Олег | Лебедев | 2000-02-07 | 17 |
| 3 | Тимур | Шевченко | 1998-04-27 | 19 |
| 4 | Светлана | Иванова | 1993-08-06 | 23 |
| 5 | Олег | Ковалев | 2002-02-08 | 15 |
| 6 | Алексей | Иванов | 1993-08-05 | 23 |
| 7 | Алена | Процук | 1997-02-28 | 18 |
Рассмотрим SQL запрос подробнее.
Оператор SELECT говорит, что мы будем извлекать данные. После него идет список столцов, которые мы хотим получить. Если указать звездочку (*), как у нас, то получим все столбцы в том порядке, в котором они определены в таблице: id, first_name, last_name и тд. Далее идет конструкция FROM users, которая буквально означает ИЗ users.
То есть вся SQL конструкция читается как ВЫБРАТЬ все столбцы ИЗ таблицы users.
Теперь вместо звездочки напишем: last_name, first_name, birthday, чтобы у нас получился такой SQL-запрос:
SELECT last_name, first_name, birthday FROM users
Если его выполнить, то мы снова получим всех пользователей из таблицы users, но на этот раз только фамилию, имя и дату рождения. То есть записи все, а столбцы нет:
| id | last_name | first_name | birthday |
|---|---|---|---|
| 1 | Иванов | Дмитрий | 1996-12-11 |
| 2 | Лебедев | Олег | 2000-02-07 |
| 3 | Шевченко | Тимур | 1998-04-27 |
| 4 | Иванова | Светлана | 1993-08-06 |
| 5 | Ковалев | Олег | 2002-02-08 |
| 6 | Иванов | Алексей | 1993-08-05 |
| 7 | Процук | Алена | 1997-02-28 |
Кроме того, что мы получили не все столбцы, мы дополнительно изменили их порядок на тот, который нам удобен. В оригинальной таблице first_name стоит перед last_name, а у нас наоборот.
Еще обратите внимание, что результатом работы SQL запроса является таблица. То есть мы берем исходную таблицу, которая хранится в базе, и с помощью SQL запроса получаем другую таблицу — с теми данными, которые нам нужны.
И часто требуется получить не все данные, а только те, которые соответствуют какому-то условию. Давайте снова изменим наш SQL-запрос, чтобы он стал таким:
SELECT last_name, first_name, birthday FROM users WHERE age > 18
Если его выполнить, то мы получим список пользователей которым уже исполнилось 19 лет:
| id | last_name | first_name | birthday |
|---|---|---|---|
| 1 | Иванов | Дмитрий | 1996-12-11 |
| 3 | Шевченко | Тимур | 1998-04-27 |
| 4 | Иванова | Светлана | 1993-08-06 |
| 6 | Иванов | Алексей | 1993-08-05 |
Конструкция WHERE позволяет фильтровать исходные данные в соответствии с нашими условиями. В данном случае мы получаем данные из таблицы users ГДЕ (WHERE) в столбце age значение больше 18.
Так как age — это числовой столбец, то его уместно сравнивать с числами. Если заменить знак больше на равно и снова запустить, то получим всех 18 летних пользователей. А если поставим >= , то получим совершеннолетних пользователей:
SELECT last_name, first_name, birthday FROM users WHERE age >= 18
| id | last_name | first_name | birthday |
|---|---|---|---|
| 1 | Иванов | Дмитрий | 1996-12-11 |
| 3 | Шевченко | Тимур | 1998-04-27 |
| 4 | Иванова | Светлана | 1993-08-06 |
| 6 | Иванов | Алексей | 1993-08-05 |
| 7 | Процук | Алена | 1997-02-28 |
Как видите SQL запросы просто составлять и читать. Язык создавался для того, чтобы им могли пользоваться люди, которые не умеют программировать: менеджеры, аналитики, маркетологи. В том числе начинающие специалисты.
А теперь самое время потренироваться в SQL, для этого к каждому уроку привязано несколько задач, которые вы можете решать в специальном тренажере прямо на сайте.
Следующий урок
Урок 2. Составные условия
В этом уроке вы узнаете как формировать сложные условия в SQL-запросах с использованием операторов AND и OR.
Полный курс с практикой
- 57 уроков
- 261 задание
- Сертификат
- Поддержка преподавателя
- Доступ к курсу навсегда
- Можно в рассрочку
Руководство. создать объекты базы данных с помощью запросов
Если вы предпочитаете использовать скрипты для создания или изменения представлений, хранимых процедур, функций, триггеров и определяемых пользователем типов, то для этого можно пользоваться редактором Transact-SQL. Редактор Transact-SQL поддерживает технологии IntelliSense и другие языки. Дополнительные сведения см. в статье Использование редактора Transact-SQL для изменения и выполнения скриптов.
Редактор Transact-SQL вызывается, когда через контекстное меню Просмотр кода вы открываете любую сущность базы данных в подключенной базе данных или проекте. Кроме того, он автоматически открывается при использовании контекстного меню Создать запрос в окне обозревателя объектов SQL Server или при добавлении нового объекта скрипта в проект базы данных. Если подключение к базе данных не установлено, но нужно выполнить к ней запрос, можно воспользоваться диалоговым окном Создать подключение для запроса, выбрав пункт Редактор Transact-SQL в меню SQL для подключения к базе данных и запуска редактора Transact-SQL.
В следующих процедурах используются сущности, созданные ранее с помощью руководства по разработке подключенной базы данных.
Создание таблицы с помощью запроса Transact-SQL
- Щелкните правой кнопкой мыши узел базы данных Trade и выберите Создать запрос.
- Вставьте следующий код в области скрипта:
CREATE TABLE [dbo].[Fruits] ( [Id] INT NOT NULL, [Perishable] BIT DEFAULT ((1)) NULL, PRIMARY KEY CLUSTERED ([Id] ASC), FOREIGN KEY ([Id]) REFERENCES [dbo].[Products] ([Id]) );
Создание новой функции
- Замените код в текущем окне редактора Transact-SQL приведенным ниже кодом.
CREATE FUNCTION [dbo].GetProductsBySupplier ( @SupplierId int ) RETURNS @returntable TABLE ( [Id] int NOT NULL, [Name] NVARCHAR (128) NOT NULL, [Shelflife] INT NOT NULL, [SupplierId] INT NOT NULL, [CustomerId] INT NOT NULL ) AS BEGIN INSERT @returntable SELECT * from Products p where p.SupplierId = @SupplierId RETURN END
Создание нового представления
- Замените код в текущем окне редактора Transact-SQL приведенным ниже кодом. Затем нажмите кнопку Выполнить запрос над редактором, чтобы выполнить этот запрос.
CREATE VIEW [dbo].PerishableFruits AS SELECT p.Id, p.Name FROM dbo.Products p join dbo.Fruits f on f.Id = p.Id where f.Perishable = 1
Скрипты Simple-Scada
В базе данных можно создавать таблицы, добавлять в них строки с данными, удалять, редактировать их и т.д. Все эти действия выполняются через SQL-запросы к БД. Например, чтобы добавить новую строку в таблицу «my_table» с двумя целочисленными столбцами, нужно выполнить соответствующий SQL-запрос:
INSERT INTO `my_table` (col1, col2) VALUES (11, 65);
Чтобы получить содержимое таблицы «my_table», нужно выполнить SQL-запрос на выборку:
SELECT * FROM `my_table`;
Таким образом можно составить любой SQL-запрос, который будет выполнять поставленную задачу.
Важно! Обработать ошибки в SQL-запросах можно в скрипе «Ошибка SQL-запроса», например выдать ошибку в компонент «Текст». Также, для отладки скриптов работы с БД можно активировать опцию «Лог пользовательских SQL-запросов», тогда все пользовательские SQL-запросы будут записываться в лог-файл сервера. Данную опцию можно использовать только для отладки проекта, иначе она будет создавать лишнюю нагрузку на сервер скады .
Рекомендуем предварительно убедиться в том, что запрос не содержит ошибок. Например, чтобы составить и проверить SQL-запрос для MySQL, можно использовать MySQLWorkbench.
Когда SQL-запрос подготовлен и проверен, можно вызвать его из скрипта Simple-Scada. Для выполнения пользовательских SQL-запросов в Simple-Scada используется процедура RunSQL — в нее нужно передать код SQL-запроса и скада автоматически отправит этот запрос на выполнение. Допустим у нас имеется следующий SQL-запрос:
INSERT INTO `my_table` (col1, col2) VALUES (11, 65);
Требуется выполнить его, когда пользователь нажмет на кнопку. Для этого нужно выделить кнопку и на событие OnClick написать скрипт со следующим кодом:
var
aQuery: string ;
begin
< Формируем запрос к БД >
aQuery := ‘INSERT INTO `my_table` (col1, col2) VALUES (11, 65);’ ;
< Отправляем запрос на выполнение c тегом = 0>
RunSQL(aQuery, nil , 0 );
end .
Сначала мы записали текст SQL-запроса в строковую переменную aQuery, а затем вызвали процедуру RunSQL с этой строковой переменной. Далее, скада автоматически отправит наш запрос в БД. Если запрос выполнится успешно (без ошибок), то скада вызовет все скрипты с типом события «Выполнен SQL-запрос». Если при выполнении запроса что-то пойдет не так (например, в запросе имеется ошибка), то скада вызовет скрипты с типом события «Ошибка SQL-запроса».
Порядок выполнения запросов
Все запросы к БД выполняются асинхронно. БД выполняет каждый запрос в отдельном потоке, т.е. если отправить в БД несколько запросов подряд, то они будут выполняться одновременно в разных потоках и то, какой запрос выполнится быстрее зависит от множества факторов, например нагрузки на процессор, нагрузки на саму БД, количества других запросов выполняющихся в данный момент и т.д. Поэтому, если обязательно требуется выполнить запросы последовательно, то нужно отправить в БД первый запрос, пометив его уникальным тегом. Затем в скрипте «Выполнен SQL-запрос» необходимо проверить, что выполнился запрос помеченный нужным тегом(if DataSet.Tag = ?? then), после чего можно отправить в БД второй запрос.
Одинарные кавычки в SQL-запросах
Пусть мы хотим выполнить такой SQL-запрос: » INSERT INTO `my_table` (col1, col2) VALUES (‘привет’, ‘мир’); «. В этом запросе есть одинарные кавычки, в них мы передаём строковые константы (‘привет’ и ‘мир’). Теперь, если мы подставим этот запрос в процедуру RunSQL, то получим ошибку компилятора, например:
var
aQuery: string ;
begin
< Формируем запрос к БД >
aQuery := ‘INSERT INTO `my_table` (col1, col2) VALUES (‘ привет ‘, ‘ мир ‘);’ ; // ошибка синтаксиса!
< Отправляем запрос на выполнение c тегом = 0>
RunSQL(aQuery, nil , 0 );
end .
Дело в том, что SQL-запросы передаются в RunSQL в виде строки, а строки должны быть заключены в одинарные кавычки. Наши одинарные кавычки внутри SQL-запроса мешают компилятору правильно воспринимать строку (это видно даже по подсветке синтаксиса в примере выше). Чтобы решить проблему, нужно продублировать одинарные кавычки в SQL-запросе, вот так:
var
aQuery: string ;
begin
< Формируем запрос к БД >
aQuery := ‘INSERT INTO `my_table` (col1, col2) VALUES (»привет», »мир»);’ ;
< Отправляем запрос на выполнение c тегом = 0>
RunSQL(aQuery, nil , 0 );
end .
Теперь компилятор правильно воспринимает весь запрос как единую строку.
Есть ещё один вариант для решения проблемы с одинарными кавычками. Можно использовать функцию QuotedStr, которая добавляет одинарные кавычки по краям строки. Например:
var
aQuery: string ;
begin
< Формируем запрос к БД >
aQuery := ‘INSERT INTO `my_table` (col1, col2) VALUES (‘ + QuotedStr( ‘привет’ ) + ‘, ‘ + QuotedStr( ‘мир’ ) + ‘);’ ;
< Отправляем запрос на выполнение c тегом = 0>
RunSQL(aQuery, nil , 0 );
end .
Длинные SQL-запросы в коде
Пусть у нас есть длинный SQL-запрос: » INSERT INTO `my_table` (col1, col2, col3, col4, col5, col6) VALUES (11, 65, 25.15, ‘текст1’, ‘текст2’, ‘текст3’); «. Если вписать его одной строкой, то на экране может просто не хватить места по ширине из-за чего придётся пользоваться горизонтальным скроллом. Правильнее будет разбить текст запроса на три строки, каждую строку заключить в одинарные кавычки и сложить их знаком «+». Вот так:
var
aQuery: string ;
begin
< Формируем запрос к БД >
aQuery := ‘INSERT INTO `my_table` ‘ +
‘(col1, col2, col3, col4, col5, col6) VALUES ‘ +
‘(11, 65, 25.15, »текст1», »текст2», »текст3»);’ ;
< Отправляем запрос на выполнение c тегом = 0>
RunSQL(aQuery, nil , 0 );
end .
Разбиение на строки полезно, так как улучшает читаемость кода.
Как понять что запрос выполнился
Пусть в проекте есть кнопка, по нажатию на которую в таблице «my_table» создаётся новая строка. Т.е. на событие OnClick написан такой код:
var
aQuery: string ;
begin
< Формируем запрос к БД >
aQuery := ‘INSERT INTO `my_table` (col1, col2) VALUES (11, 65);’ ;
< Отправляем запрос на выполнение c тегом = 0>
RunSQL(aQuery, nil , 0 );
end .
Теперь мы добавили на мнемосхему компонент текст с именем «Text1» и хотим, чтобы после выполнения нашего SQL-запроса текст изменился на «Мой запрос выполнен!». Тогда мы должны, во-первых, при вызове RunSQL пометить наш запрос каким-то уникальным тегом, который больше никогда нами в RunSQL не использовался, например 55:
var
aQuery: string ;
begin
< Формируем запрос к БД >
aQuery := ‘INSERT INTO `my_table` (col1, col2) VALUES (11, 65);’ ;
< Отправляем запрос на выполнение c тегом = 55 >
RunSQL(aQuery, nil , 55 );
end .
Во-вторых, необходимо создать в меню скриптов новый скрипт с типом события «Выполнен SQL-запрос». Такой скрипт будет вызываться скада-системой каждый раз, когда выполнился любой пользовательский SQL-запрос. Также, этот скрипт будет содержать параметр «DataSet» — результат выполнения запроса. У параметра DataSet имеется свойство Tag. Это и есть тот самый тег, который мы назначили при выполнении RunSQL. Таким образом, по значению тега мы можем узнать в скрипте какой именно из наших SQL-запросов выполнился. Например:
begin
if DataSet.Tag = 55 then
Text1.Text := ‘Запрос выполнен!’ ;
end .
Блокировка кнопки на время выполнения запроса
Допустим имеется кнопка, по нажатию на которую выполняется запрос к БД. Требуется блокировать кнопку на время выполнения запроса для предотвращения повторных нажатий. Для решения этой задачи на событие OnClick кнопки нужно написать код запроса к БД, а также пометить запрос уникальным тегом, который ранее не использовался в RunSQL, например 77:
Далее, создадим новый скрипт с типом события «Выполнен SQL-запрос» и следующим кодом:
begin
if DataSet.Tag = 77 then // если запрос помеченный тегом 77 выполнен, то
Button1.Enabled := True; // разблокируем кнопку
end .
Метод RunSQL компонента «Таблица»
У компонента «Таблица» есть свой внутренний метод RunSQL, который удобно использовать для того чтобы отобразить результат выполнения SQL-запроса в таблице на мнемосхеме. Например можно создать на мнемосхеме таблицу с именем «Table1», разместить рядом кнопку «Считать» и на событие OnClick кнопки написать такой код:
Теперь при нажатии на кнопку «Считать» скада выполнит SQL-запрос, а после выполнения автоматически отобразит результат в таблице Table1. Если запрос выполнится с ошибкой, то текст ошибки отобразится в таблице. Другие примеры для метода RunSQL таблицы можно найти по ссылке.

Работа с выборкой из множества строк
Пример работы с выборкой из множества строк можно найти по ссылке.