Форум программистов, компьютерный форум, киберфорум
C#: Базы данных
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.85/41: Рейтинг темы: голосов - 41, средняя оценка - 4.85
54 / 6 / 5
Регистрация: 24.01.2019
Сообщений: 171
MS SQL

ID связанных таблиц 2

17.05.2020, 11:06. Показов 8529. Ответов 88
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток, нужен совет(подсказка, пример) по следующей задаче:
Имеются в БД(MSSQL) две таблицы, головная "Покупки" и дополнительная "ПокупкаИнфо".
У первой есть первичный уникальный ключ, по полю ID(со свойством IDENTITY).
У второй таблицы есть составной "PRIMARY KEY(ПокупкаID,LineItem)".

Получается связка такая, на каждый уникальный "Покупки.ID" приходится по нескольку "ПокупкаИнфо.ПокупкаID".
С "Покупки.ID" автоматически(в SQL) создаётся новый номер.
А вот с "ПокупкаИнфо.ПокупкаID" возникает вопрос:
Как в С# сделать так , что бы для "ПокупкаИнфо.ПокупкаID" присваивался тот же номер что и у "Покупки.ID" ?

Эта же тема была тут: ID связанных таблиц
Но там сказали пойти сюда)
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
17.05.2020, 11:06
Ответы с готовыми решениями:

Сохранение связанных таблиц
Доброго времени суток! Проблема заключается в том что у меня есть три таблицы в БД, Специальность->Группа->Абитуриент...

Отображение связанных таблиц
Здравствуйте Не подскажите как такое можно реализовать? Есть 2 таблицы на форме. Они связаны 2 ключом. Получается, выделяешь строку в...

Работа с Id из связанных таблиц
Всем доброго времени суток!!! Работаю на языке с# c средой разработки баз данных ms sql server Вывел с базы данных информацию одной из...

88
800 / 583 / 207
Регистрация: 21.02.2019
Сообщений: 2,095
18.05.2020, 10:58
7-2-3,
.. привязываться к автоинкрементному полю не очень правильно для связанных таблиц, ибо вы не знаете его значения в момент создания записи ... лучше создать свое поле с GUID, который будет генерироваться в коде C# перед INSERT-ом, или создавать номер типа INTEGER путем предварительного запроса SELECT MAX - но при многопользовательской работе может где-то что-то пойти не так ... кстати, начиная с ms sql 2016 можно хранить вложенные данные в поле типа JSON_VALUE, если что ...
0
785 / 616 / 273
Регистрация: 04.08.2015
Сообщений: 1,713
18.05.2020, 14:25
7-2-3, вы создаете новую запись в таблице Покупки, получаете ее ID, подставляете его в ПокупкаИнфо.ПокупкаID. В чем сложность?
1
800 / 583 / 207
Регистрация: 21.02.2019
Сообщений: 2,095
18.05.2020, 15:36
Цитата Сообщение от Igr_ok Посмотреть сообщение
получаете ее ID
... если не использовать хранимку, где можно получить этот ID через SCOPE_IDENTITY, то можно налететь на дву- (а то и много-) значность при многопользовательской работе ...
0
785 / 616 / 273
Регистрация: 04.08.2015
Сообщений: 1,713
18.05.2020, 16:11
Цитата Сообщение от carrotik Посмотреть сообщение
... если не использовать хранимку, где можно получить этот ID через SCOPE_IDENTITY, то можно налететь на дву- (а то и много-) значность при многопользовательской работе ...
И как тогда работает InsertCommand в DataAdapter? Если не можете написать код самостоятельно, создайте DataAdapter в дизайнере и скопируйте оттуда.
0
54 / 6 / 5
Регистрация: 24.01.2019
Сообщений: 171
18.05.2020, 19:46  [ТС]
Igr_ok, а можно примерчик ? Если Вас не затруднит конечно.
0
785 / 616 / 273
Регистрация: 04.08.2015
Сообщений: 1,713
18.05.2020, 22:28
Цитата Сообщение от 7-2-3 Посмотреть сообщение
а можно примерчик ?
C#
1
2
3
4
5
6
7
8
SqlCommand cmd = new SqlCommand("INSERT INTO [Покупки] ([PrihodDate], [ПоставщикID]) VALUES (@PrihodDate, @ПоставщикID); set @ID=SCOPE_IDENTITY()", sqlConnection1);
cmd.Parameters.AddWithValue("@PrihodDate", DateTime.Now);
cmd.Parameters.AddWithValue("@ПоставщикID", DBNull.Value);
cmd.Parameters.AddWithValue("@ID", 0).Direction = ParameterDirection.Output;
sqlConnection1.Open();
cmd.ExecuteNonQuery();
//cmd.Parameters["@ID"].Value возвращает созданный ID
sqlConnection1.Close();
1
54 / 6 / 5
Регистрация: 24.01.2019
Сообщений: 171
29.09.2020, 16:03  [ТС]
Я создал подобную строку, но у меня почему то ругается на скобочки возле "conn" (sqlConnection):
C#
1
myCommand.CommandText = ("INSERT INTO Покупки (ПоставщикID, PrihodDate) VALUES (@ПоставщикID, @PrihodDate); set @ПокупкаID = SCOPE_IDENTITY()", conn) ;
Не пойму, чего ему не хватает ?
Миниатюры
ID связанных таблиц 2  
0
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
29.09.2020, 16:37
Цитата Сообщение от carrotik Посмотреть сообщение
. привязываться к автоинкрементному полю не очень правильно для связанных таблиц, ибо вы не знаете его значения в момент создания записи ... лучше создать свое поле с GUID, который будет генерироваться в коде C# перед INSERT-ом, или создавать номер типа INTEGER путем предварительного запроса SELECT MAX - но при многопользовательской работе может где-то что-то пойти не так ... кстати, начиная с ms sql 2016 можно хранить вложенные данные в поле типа JSON_VALUE, если что ...
Очень спорное утверждение.

Во-первых, в 3N базах привязка дочерних таблиц к главным делается именно по UID.

Во-вторых, получить ID только что вставленной записи не сложно (@@IDENTITY, SCOPE_IDENTITY). Т.е. так:
SQL
1
2
3
4
DECLARE @NewMasterId INT
INSERT INTO MASTER () ...
SET @BewMasterID = (SELECT @@IDENTITY)
INSERT INTO DETAIL (.., PID, ..) VALUES (..,@NewMasterID,..)
Главное, чтобы все эти запросы выполнялись в контексте одной транзакции.

А вот SELECT MAX(ID) действительно неправильно ибо высокая гарантия получения ошибок.
Вообще, использование простого INT (BIGINT) в качестве UID (уникального идентификатора) весьма сомнительно, т.к. его уникальность никак не обеспечена SQL-сервером.
Использование GUI вместо UI, конечно, возможно. Но при отладке делает визуальный контроль связок весьма затруднительным.

Добавлено через 4 минуты
Цитата Сообщение от 7-2-3 Посмотреть сообщение
Я создал подобную строку, но у меня почему то ругается на скобочки возле "conn" (sqlConnection):
В вашей строке содержатся как параметры, которые Вы непонятно как создаете и инициализируете, так и ссылка на SQL- переменную, которые нигде в скрипте не объявляется.
И, наконец, что за привычка обзывать таблицы и поля кириллицей. А если уж чешется, то берите их в кв.скобки.

Добавлено через 7 минут
Кстати, объявление int-переменной и присвоение ей нового значения ID необязательны.
Вполне достаточно такого:

SQL
1
2
INSERT INTO Master (Name) VALUES('Вася')
INSERT INTO Detail (PID, Subject, Assessment) VALUES ((SELECT @@IDENTITY),'ASP.NET','2 балла')
1
 Аватар для Andrey-MSK
3360 / 2246 / 388
Регистрация: 14.08.2018
Сообщений: 7,588
Записей в блоге: 4
29.09.2020, 16:41
Цитата Сообщение от MsGuns Посмотреть сообщение
Вообще, использование простого INT (BIGINT) в качестве UID (уникального идентификатора) весьма сомнительно, т.к. его уникальность никак не обеспечена SQL-сервером.
INT в ключевом поле с IDENTITY никогда не повторится, даже если вы удаляете записи из таблицы. Сбросить это значение в 0 можно только в случае применения TRUNCATE, а такое, на рабочей базе с заполненными таблицами, в здравом уме никто делать не будет
1
54 / 6 / 5
Регистрация: 24.01.2019
Сообщений: 171
29.09.2020, 17:07  [ТС]
Вот так выглядит код моей красивой кнопочки:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
private void button3_Click(object sender, EventArgs e)
        {
           
            if (comboBox1.Text == "")
            {
                MessageBox.Show("Заполните все поля!");
            }
            else
            {
                try
                {
                    
 
 
                    int ПоставщикID = int.Parse(label22.Text);
                    DateTime PrihodDate = Convert.ToDateTime(dateTimePicker1.Text);
 
                    conn = new SqlConnection();
                    conn.ConnectionString = @"Data Source=RR-PC\SQL150916;Initial Catalog=Base5;Integrated Security=True";
                    conn.Open();
                    
 
                    SqlCommand myCommand = conn.CreateCommand();
                    myCommand.CommandText = "INSERT INTO [Покупки] ([ПоставщикID], PrihodDate) VALUES (@ПоставщикID, @PrihodDate);set @ID = SCOPE_IDENTITY()", conn) ; // вот тут студия ругается на отсутствие скобочек, как на картинке выше
                    myCommand.Parameters.Add("@PrihodDate", SqlDbType.DateTime, 8);
                    myCommand.Parameters["@PrihodDate"].Value = PrihodDate;
                    myCommand.Parameters.Add("@ПоставщикID", SqlDbType.Int, 4);
                    myCommand.Parameters["@ПоставщикID"].Value = ПоставщикID;
                    myCommand.Parameters.AddWithValue("@ID", 0).Direction = ParameterDirection.Output;
                    //myCommand.Parameters["@ID"].Value= textBox5;
 
                    myCommand.ExecuteNonQuery();
                    int Change = myCommand.ExecuteNonQuery();
                    if (Change != 0)
 
                    {
                        MessageBox.Show("Изменения внесены", "Изменение записи");
                    }
                    else
                    {
                        MessageBox.Show("He удалось внести изменения", "Изменение записи");
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
                finally
                {
                    conn.Close();
                    comboBox1.SelectedIndex = -1;
                }
                this.покупкиTableAdapter1.Fill(this.base5DataSet13.Покупки);
                this.tabControl1.SelectedTab = tabPage1;
 
            }
 
 
        }
Но она не работает, из-за проблем на 24 строке.
0
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
29.09.2020, 17:24
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
INT в ключевом поле с IDENTITY никогда не повторится
Ключевое слово "простого". А это вовсе не IDENTITY
0
 Аватар для Andrey-MSK
3360 / 2246 / 388
Регистрация: 14.08.2018
Сообщений: 7,588
Записей в блоге: 4
29.09.2020, 17:24
7-2-3, ну вы не правильно записали код и сообщения №7 Там объявление команды другое. Удалите вот это у себя в строке 24
Code
1
, conn)
, либо объявите команду как в сообщении №7.
1
785 / 616 / 273
Регистрация: 04.08.2015
Сообщений: 1,713
29.09.2020, 17:25
Найдите отличие
Цитата Сообщение от Igr_ok Посмотреть сообщение
C#
1
SqlCommand cmd = new SqlCommand("INSERT INTO [Покупки] ([PrihodDate], [ПоставщикID]) VALUES (@PrihodDate, @ПоставщикID); set @ID=SCOPE_IDENTITY()", sqlConnection1);
Цитата Сообщение от 7-2-3 Посмотреть сообщение
C#
1
myCommand.CommandText = "INSERT INTO [Покупки] ([ПоставщикID], PrihodDate) VALUES (@ПоставщикID, @PrihodDate);set @ID = SCOPE_IDENTITY()", conn) ;
Если не получится, смотрите спойлер
Кликните здесь для просмотра всего текста
Вы текстовой переменной присваиваете значения строка, connection
1
 Аватар для Andrey-MSK
3360 / 2246 / 388
Регистрация: 14.08.2018
Сообщений: 7,588
Записей в блоге: 4
29.09.2020, 17:27
MsGuns, у ТС в главной таблице ID как раз IDENTITY
0
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
29.09.2020, 17:32
Цитата Сообщение от 7-2-3 Посмотреть сообщение
Но она не работает, из-за проблем на 24 строке.
И не будет работать

Вы не полностью прочитали и осознали [9]
У Вас используется не запрос, а скрипт, т.е. блок, объединяющий несколько разных команд серверу.
Конструкция SET присваивает переменной какое-то значение. Но в Вашем скрипте она не объявлена.
Далее Вы с этой переменной ничего не делаете. Сервер присвоит переменной ID значение нового айдишника и.. завершит транзакцию. Куда денется этот самый ID ? Правильно - канет в Лету.

Добавлено через 2 минуты
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
MsGuns, у ТС в главной таблице ID как раз IDENTITY
Мой пост, который Вы комментируете, относился к высказыванию [2], где речь, в частности, шла о SELECT MAX и фразе :
Цитата Сообщение от carrotik Посмотреть сообщение
привязываться к автоинкрементному полю не очень правильно для связанных таблиц
1
54 / 6 / 5
Регистрация: 24.01.2019
Сообщений: 171
29.09.2020, 17:36  [ТС]
Ага, спасибо. Поправил вот на это:
C#
1
 SqlCommand myCommand = new SqlCommand ("INSERT INTO [Покупки] ([ПоставщикID], PrihodDate) VALUES (@ПоставщикID, @PrihodDate);set @ID = SCOPE_IDENTITY()", conn) ;
А теперь, мне нужно воспользоваться вот этой строкой:
C#
1
//cmd.Parameters["@ID"].Value возвращает созданный ID
Что бы вставить полученный ID, туда куда мне нужно , да ? Или я не правильно понял строку ?
0
 Аватар для Andrey-MSK
3360 / 2246 / 388
Регистрация: 14.08.2018
Сообщений: 7,588
Записей в блоге: 4
29.09.2020, 17:46
7-2-3, да
C#
1
intIDLast = cmd.Parameters["@ID"].Value
1
54 / 6 / 5
Регистрация: 24.01.2019
Сообщений: 171
29.09.2020, 18:38  [ТС]
Думал выведу его в textBox , состряпал вот такое вот:
C#
1
2
object intIDLast = int.Parse(textBox5.Text);  //240 строка
 myCommand.Parameters["@ID"].Value =intIDLast ;
Но при выполнении получил вот это:
System.FormatException: Входная строка имела неверный формат.

в System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)

в System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)

в System.Int32.Parse(String s)

в WindowsFormsApplication1.Form7.button3_C lick(Object sender, EventArgs e) в C:\Users\RR\Documents\Visual Studio 2015\Projects\2017\WindowsFormsApplicati on1\WindowsFormsApplication1\Form7.cs:ст рока 240
---------------------------
ОК



Добавлено через 1 минуту
Поменял на
C#
1
object intIDLast = Convert.ToString(this.textBox5.Text);
выполнение проходит, а textBox пустой остаётся.
0
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
30.09.2020, 00:50
Цитата Сообщение от 7-2-3 Посмотреть сообщение
Думал выведу его в textBox , состряпал вот такое вот:
И где это у Вас в текстбокс "выводится" ?
В коде берется как раз из него. При этом "пустышка" радостно всовывается в int.Parse Тогда бы уж юзали TryParse, там по крайней мере не "вылетит", если в боксе не цифры.

Ну и это "загадочное" object. Это чтоб никто не догадался ?

А по сути..
Сиквель из [9] так и не удосужились разобрать ?

Добавлено через 4 минуты
И еще. Обратите внимание на эту фразу:
Цитата Сообщение от MsGuns Посмотреть сообщение
Главное, чтобы все эти запросы выполнялись в контексте одной транзакции.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
30.09.2020, 00:50
Помогаю со студенческими работами здесь

Выборка данных из связанных таблиц
Всем привет! Столкнулся с проблемой выборки данных из связанных таблиц.Есть БД Access, читаю с помощью OLEDB. Есть 2 таблицы: 1...

Вывод связанных таблиц в DataGridView
Здравствуйте. Имеются три таблицы: Books (со столбцами ID, Name, Author, Genre), Authors (со столбцами ID, Name, Surname), Genres (со...

Обновление связанных таблиц в DataGridView
Всем привет. Возник такой вопрос: как можно обновить связанную таблицу при программной сортировке главной? Я сортирую результаты главной...

Обновление связанных таблиц в datagridview
Есть кнопка на вывод информации: SqlConnection con; SqlDataAdapter sda; SqlCommandBuilder scb; ...

Отображение полей связанных таблиц
Здравствуйте. Существуют таблицы: Товары, тип товара, категория. "Тип товара" связанны с "категорией", а "товары" с...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Доступность команды формы по условию
Maks 07.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: сделать доступной кнопку (команда формы "ЗавершитьСписание") при. . .
Уведомление о неверно выбранном значении справочника
Maks 06.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "НарядПутевка", разработанного в конфигурации КА2. Задача: уведомлять пользователя, если в документе выбран неверный склад. . .
Установка Qt Creator для C и C++: ставим среду, CMake и MinGW без фреймворка Qt
8Observer8 05.04.2026
Среду разработки Qt Creator можно установить без фреймворка Qt. Есть отдельный репозиторий для этой среды: https:/ / github. com/ qt-creator/ qt-creator, где можно скачать установщик, на вкладке Releases:. . .
AkelPad-скрипты, структуры, и немного лирики..
testuser2 05.04.2026
Такая программа, как AkelPad существует уже давно, и также давно существуют скрипты под нее. Тем не менее, прога живет, периодически что-то не спеша дополняется, улучшается. Что меня в первую очередь. . .
Отображение реквизитов в документе по условию и контроль их заполнения
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеСпецтехники", разработанного в конфигурации КА2. Данный документ берёт данные из другого нетипового документа. . .
Фото всей Земли с борта корабля Orion миссии Artemis II
kumehtar 04.04.2026
Это первое подобное фото сделанное человеком за 50 лет. Снимок называют новым вариантом легендарной фотографии «The Blue Marble» 1972 года, сделанной с борта корабля «Аполлон-17». Новое фото. . .
Вывод диалогового окна перед закрытием, если документ не проведён
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать программный контроль на предмет проведения документа. . .
Программный контроль заполнения реквизитов табличной части документа
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: 1. Реализовать контроль заполнения реквизита. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru