Форум программистов, компьютерный форум, киберфорум
Delphi: Базы данных
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.67/21: Рейтинг темы: голосов - 21, средняя оценка - 4.67
0 / 0 / 0
Регистрация: 08.06.2013
Сообщений: 70
1

Многотабличный запрос sql access, загрузка в одну таблицу данных из нескольких

18.11.2014, 14:34. Показов 4177. Ответов 32
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
в продолжение темы подскажите в такой проблеме нужно на основании имеющегося ключевого поля вывести таблицу связанную с ней, а в той таблице несколько полей связаны с другими таблицами, в аксесе я вижу те данные которые я выбрал в списке данных из других таблиц, а в делфи я вижу id выбранных данных

вот по такому запросу выходит пустая таблица
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
procedure TBase_client.ComboBox2Select(Sender: TObject);
begin
kod:=integer(ComboBox2.Items.Objects[ComboBox2.ItemIndex]);
  with AdoQuery2 do
    begin
      Close;
      SQL.Clear;
      SQL.Add('SELECT relatives.Фамилия, relatives.Имя, relatives.Отчество, client.Телефон, ');
      SQL.Add('client.Электронная почта, client.Дата_рождения, client.Мать, client.Отец,');
      SQL.Add('client.[Брат\Сестра], doct.Учёт, doct.Специализация, client.Дата_Время_приёма, client.Причина');
      SQL.Add('FROM relatives INNER JOIN ((base INNER JOIN groups ON base.Код = groups.ParentID)');
      SQL.Add('INNER JOIN (doct INNER JOIN client ON doct.Код = client.Учёт_врача) ON groups.Код = client.ParentID)');
      SQL.Add('ON (base.id = relatives.id) AND (relatives.id = client.[Брат\Сестра]) AND (relatives.id = client.Отец)');
      SQL.Add('AND (relatives.id = client.Мать) AND (relatives.id = client.ФИО_клиента)WHERE 
      (((client.Parentid) = :kod))');
      Parameters.ParamByName('kod').Value:=kod;
      Open;
      First;
    end;
end;
Вот по такому запросу строиться таблица но с id а не с содержимым ячеек
Delphi
1
2
3
4
5
6
7
8
9
 with AdoQuery2 do
    begin
      Close;
      SQL.Clear;
      SQL.Add('SELECT * FROM client WHERE Parentid = :Группа');
      Parameters.ParamByName('Группа').Value:= kod;
      Open;
      First;
    end;
подскажите как подправить запрос
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
18.11.2014, 14:34
Ответы с готовыми решениями:

Access 2003. Добавление данных из нескольких полей в одну таблицу
Нужна помощь знающих людей. Необходимо, после нажатия кнопки <Ввод данных>, добавить введенные...

SQL запрос на добавление данных из VBA Excel в таблицу Access
Добрый день, форумчане! Столкнулся с ошибкой запроса на добавление при попытке передать данные из...

Необходимо составить многотабличный запрос на sql
Имеется база данных Склад телефонов. Приведенный ниже запрос выводит информацию о клиентах,...

Записать данных из нескольких файлов Excel в одну таблицу
Доброго времени суток, форумчане! Возник вопрос с занесением данных из нескольких файлов Excel в...

32
1074 / 987 / 340
Регистрация: 07.08.2012
Сообщений: 2,790
02.12.2014, 16:46 21
Author24 — интернет-сервис помощи студентам
Теперь понятно о какой потере связи идет речь.
Связь "потеряна" только потому что ссылки на вновь созданные строки не пишутся в базу.
А надо. Ниже показано как.
Кликните здесь для просмотра всего текста
Delphi
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
  with Create_client.AdoQuery3 do begin
      //вначале записываем ф и о клиента
    SQL.Text:='INSERT INTO relatives(Фамилия, Имя, Отчество) values ('+
      #39+Create_client.Edit1.Text+#39','#39+Create_client.Edit2.Text+#39','#39+
      Create_client.Edit3.Text+#39')';
    ExecSQL;
      //берем идентификатор только что записанной в таблицу relatives строки -
      //это будет ИД, с помощью которого осуществляется связь между таблицами
      //сохраняем полученное значение в переменной до будущего использования (ниже)
    SQL.Text := 'SELECT @@identity as ID';
    Open;
    KodS := FieldValues['ID'];
 
      //записываем ф и о матери и так же берем из базы новый идентификатор, запоминаем в другой переменной 
    SQL.Text:='INSERT INTO relatives(Фамилия, Имя, Отчество) values ('+
      #39+Create_client.Edit8.Text+#39','#39+Create_client.Edit9.Text+#39','#39+
      Create_client.Edit10.Text+#39')';
    ExecSQL;
    SQL.Text := 'SELECT @@identity as ID';
    Open;
    KodM := FieldValues['ID'];
 
      //записываем ф и о отца
    SQL.Text:='INSERT INTO relatives(Фамилия, Имя, Отчество) values ('+
      #39+Create_client.Edit7.Text+#39','#39+Create_client.Edit13.Text+#39','#39+Create_client.Edit14.Text+#39')';
    ExecSQL;
      //и так же вытаскиваем новое значение идентификатора (поле id)
    SQL.Text := 'SELECT @@identity as ID';
    Open;
    KodO := FieldValues['ID'];
 
      //пишем родственников и новое значение идентификатора сохраняем в отдельной переменной
    SQL.Text:='INSERT INTO relatives(Фамилия, Имя, Отчество) values ('+
      #39+Create_client.Edit16.Text+#39','#39+Create_client.Edit17.Text+#39','#39+Create_client.Edit18.Text+#39')';
    ExecSQL;
    SQL.Text := 'SELECT @@identity as ID';
    Open;
    KodR := FieldValues['ID'];
 
      //при записи в таблицу doct тоже надо брать значение нового идентификатора
      //и записывать в таблицу client поля Учёт_врача (здесь не сделано)
    SQL.Text:='INSERT INTO doct(Диагноз, Специализация) values('+
      #39+Create_client.Edit19.Text+#39','#39+Create_client.Edit15.Text+#39')';
    ExecSQL;
 
      //теперь в переменных KodS, KodM, KodO и KodК находятся ссылочные идентификаторы
      //они записываются в таблицу client. Связь не теряется.
    SQL.Text:='INSERT INTO client( Телефон, Электронная_почта, Дата_рождения,'+
      'Причина, Дата_Время_приёма, Пол, ParentID, ФИО_Клиента, Мать, Отец, Родственники) values ('+
      #39+Create_client.Edit4.Text+#39','#39+Create_client.Edit5.Text+#39','#39+Create_client.Edit6.Text+#39','+
      #39+Create_client.Edit11.Text+#39','#39+Create_client.Edit12.Text+#39','#39+s+#39+
      IntToStr(KodS)+','+IntToStr(KodM)+','+IntToStr(KodO)+','+IntToStr(KodR)+','+')';
    ExecSQL;


Еще. Связи, сформированные в Аксессе будут мешать, поэтому там схему связей надо убрать
0
0 / 0 / 0
Регистрация: 08.06.2013
Сообщений: 70
03.12.2014, 08:28  [ТС] 22
В клиент записывается как надо, но связи с groups всё равно нет, то есть при выборе группы в комбобоксе2 в dbgrid появляется одна уже имеющаяся запись, вновь введённой нет, пробовал по аналогии вот так:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
kod:=integer(Create_client.ComboBox2.Items.Objects[Create_client.ComboBox2.ItemIndex]);
SQL.Text:='SELECT DISTINCT Êîä, Ãðóïïà FROM groups WHERE ParentID = :Êîä';
      Parameters.ParamByName('Êîä').Value:=kod;
      SQL.Text := 'SELECT @@identity as ID';
      Open;
      KodP := FieldValues['ID'];
      ExecSQL;
      SQL.Text:='INSERT INTO client( Òåëåôîí, Ýëåêòðîííàÿ_ïî÷òà, Äàòà_ðîæäåíèÿ,'+
      'Ïðè÷èíà, Äàòà_Âðåìÿ_ïðè¸ìà, Ïîë, ÔÈÎ_Êëèåíòà, Ìàòü, Îòåö, Ðîäñòâåííèêè, Ó÷¸ò_âðà÷à, ParentID ) values ('+
      #39+Create_client.Edit4.Text+#39','#39+Create_client.Edit5.Text+#39','#39+Create_client.Edit6.Text+#39','+
      #39+Create_client.Edit11.Text+#39','#39+Create_client.Edit12.Text+#39','#39+s+#39','+
      #39+KodC+#39','#39+KodM+#39','#39+KodO+#39','#39+KodR+#39','#39+KodD+#39','#39+KodP+#39')';
      ExecSQL;
этот же код я использую, при загрузке в dbgrid
Delphi
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
procedure TCreate_client.ComboBox1Select(Sender: TObject);
begin
kod:=integer(ComboBox1.Items.Objects[ComboBox1.ItemIndex]);
ComboBox2.Clear;
  with AdoQuery1 do
    begin
      Close;
      SQL.Clear;
      SQL.Add('SELECT DISTINCT Êîä, Ãðóïïà FROM groups WHERE Parentid = :Êîä');
      Parameters.ParamByName('Êîä').Value:=kod;
      Open;
      First;
    end;
  while not AdoQuery1.EOF do
    begin
      ComboBox2.Items.AddObject(AdoQuery1.FieldByName('Ãðóïïà').AsString,TObject(AdoQuery1.FieldByName('Êîä').AsInteger));
      AdoQuery1.Next;
    end;
end;
 
procedure TCreate_client.ComboBox2Select(Sender: TObject);
var
  Od : TOpenDialog;
begin
Od := OpenDialog1;
Od.InitialDir := ExtractFilePath( Application.ExeName );
Od.FileName:=Od.InitialDir + '\kartaf.dot';
  if not FileExists(Od.FileName) then begin
    MessageDlg(
      'Ôàéë ñ çàäàííûì èìåíåì íå íàéäåí. Äåéñòâèå îòìåíåíî.'
      ,mtWarning, [mbOK], 0);
    end;
kod:=integer(ComboBox2.Items.Objects[ComboBox2.ItemIndex]);
  with AdoQuery2 do
    begin
      Close;
      SQL.Clear;
      SQL.Add('SELECT relatives.Ôàìèëèÿ, relatives.Èìÿ, relatives.Îò÷åñòâî, client.Òåëåôîí,');
      SQL.Add('client.Ýëåêòðîííàÿ_ïî÷òà, client.Äàòà_ðîæäåíèÿ, client.Ïðè÷èíà,');
      SQL.Add('client.Äàòà_Âðåìÿ_ïðè¸ìà, client.Ïîë, doct.Äèàãíîç, doct.Ñïåöèàëèçàöèÿ,');
      SQL.Add('relatives_1.Ôàìèëèÿ AS Ôàìèëèÿ_Ìàòü, relatives_1.Èìÿ AS Èìÿ_Ìàòü, relatives_1.Îò÷åñòâî AS Îò÷åñòâî_Ìàòü,');
      SQL.Add('relatives_2.Ôàìèëèÿ AS Ôàìèëèÿ_Îòåö, relatives_2.Èìÿ AS Èìÿ_Îòåö, relatives_1.Îò÷åñòâî AS Îò÷åñòâî_Îòåö,');
      SQL.Add('relatives_3.Ôàìèëèÿ AS Ôàìèëèÿ_Ðîäñòâåííèêè, relatives_3.Èìÿ AS Èìÿ_Ðîäñòâåííèêè, relatives_3.Îò÷åñòâî AS Îò÷åñòâî_Ðîäñòâåííèêè');
      SQL.Add('FROM ((((client INNER JOIN doct ON client.Ó÷¸ò_âðà÷à = doct.id)');
      SQL.Add('INNER JOIN relatives ON client.ÔÈÎ_êëèåíòà = relatives.id)');
      SQL.Add('INNER JOIN relatives AS relatives_1 ON client.Ìàòü = relatives_1.id)');
      SQL.Add('INNER JOIN relatives AS relatives_2 ON client.Îòåö = relatives_2.id)');
      SQL.Add('INNER JOIN relatives AS relatives_3 ON client.Îòåö = relatives_3.id');
      SQL.Add('WHERE client.Parentid=:Kod');
      Parameters.ParamByName('kod').Value:=kod;
      Open;
      First;
    end;
end;
0
1074 / 987 / 340
Регистрация: 07.08.2012
Сообщений: 2,790
03.12.2014, 08:39 23
вновь введённой нет, пробовал по аналогии вот так:
Что-то не видно в приведенном фрагменте записи в таблицу Groups. Показана выборка из этой таблицы (SQL.Text:='SELECT...'), но не запись.
Отсюда бессмысленны строки получения последнего значения идентификатора, которые идут следом.
0
0 / 0 / 0
Регистрация: 08.06.2013
Сообщений: 70
04.12.2014, 05:53  [ТС] 24
у меня там связь один ко многим то есть одной записи из groups соответствует много клиентов, получается что нужно значение client.parentID связать с конкретным значением groups.Код

Добавлено через 24 минуты
там нужно элементу который уже существует добавить связь

Добавлено через 28 минут
Вот такой инсерт ничего не даёт:
Delphi
1
2
3
4
5
6
7
SQL.Text:='insert into groups(Код)'+
      'SELECT DISTINCT Код, Группа FROM groups WHERE ParentID = :Код';
      Parameters.ParamByName('Код').Value:=kod;
      SQL.Text := 'SELECT @@identity as ID';
      Open;
      KodP := FieldValues['ID'];
      ExecSQL;
Добавлено через 2 часа 18 минут
Увы, и так и сяк перекрутил не получается, та же самая проблема при создании новой групп, зависимой от базы

Добавлено через 6 часов 34 минуты
Подскажите в какую сторону копать???

Добавлено через 11 часов 11 минут
Уважаемые форумчане и глубокоуважаемый Скандерберг выручайте последний шаг остался, пробую связь с таблицей сделать таким образом

Delphi
1
2
3
4
5
       kod:=integer(Create_client.ComboBox2.Items.Objects[Create_client.ComboBox2.ItemIndex]);
      SQL.Text:='UPDATE groups INNER JOIN client on groups.Êîä=client.ParentID'''+
      'SET client.ParentID=:Kod';
      Parameters.ParamByName('Kod').Value:=kod;
      ExecSQL;
Выдаёт ошибку что параметр не найден, хотя он явно есть
0
1074 / 987 / 340
Регистрация: 07.08.2012
Сообщений: 2,790
04.12.2014, 08:19 25
в комбобоксе2 в dbgrid появляется одна уже имеющаяся запись, вновь введённой нет
Только одна запись и будет появляться, потому как DISTINCT ограничивает количество записей в результате,
возвращаемым запросом (процедура TCreate_client.ComboBox1Select):
Delphi
1
   SQL.Add('SELECT DISTINCT Код, Группа FROM groups WHERE Parentid = :Код');
Опять свободные фантазии на тему синтаксиса запросов.
Delphi
1
'UPDATE groups INNER JOIN client on groups.Код=client.ParentID...
Почему бы не прочесть внимательно что и как должен делать запрос UPDATE?
Ну, не может быть в update слова JOIN. Как правило, в update должно быть условие - в какую строку записывать изменения (после слова where).

И не очень понятно по логике проекта как группа связана с другими таблицами (таблицей).
Например, что должно быть с группой при добавлении нового клиента?
В одну группу могут входить несколько клиентов?
0
0 / 0 / 0
Регистрация: 08.06.2013
Сообщений: 70
04.12.2014, 08:29  [ТС] 26
Да, в одну группу входит несколько клиентов, при выборе конкретной группы из комбобокса2 в дбгрид загружается список к этой группе относящийся(пример: группа малоимущие в ней клиенты иванов, петров, сидоров) в группе поидее к id(Код) должна привязываться ещё одна ссылка к новому клиенту, синтаксис update брал вот из этой статьи:
http://matveev.kiev.ua/macceass/ch2/gl11/005.htm
сейчас попробую без inner join.

например если бы использовать не комбобоксы а dbgridы для отображения базы, группы и клиента, связав их по masterfield в Adoquery то запросы бы не понадобились, там все на логических связях хорошо работает, но у меня требование использовать дбгрид только для отображения клиента(((((
0
1074 / 987 / 340
Регистрация: 07.08.2012
Сообщений: 2,790
04.12.2014, 08:35 27
группе поидее к id(Код) должна привязываться ещё одна ссылка к новому клиенту,
А разве непонятно, что должно быть с точностью "до наоборот"?
В клиенте есть ссылка на группу?
Если она есть (подозреваю, что то parentID), то при добавлении нового клиента в это поле должно быть записано значение выбранной группы.
Т.е. НЕ В ГРУППЕ должна появляться ссылка на клиента, а в клиенте ссылка на группу.
Тогда связка клиента с группой становится логичной, ну и понятной.
0
0 / 0 / 0
Регистрация: 08.06.2013
Сообщений: 70
04.12.2014, 09:07  [ТС] 28
да, согласен, а как реализовать вместе с инсерт
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
SQL.Text:='INSERT INTO client( Òåëåôîí, Ýëåêòðîííàÿ_ïî÷òà, Äàòà_ðîæäåíèÿ,'+
      'Ïðè÷èíà, Äàòà_Âðåìÿ_ïðè¸ìà, Ïîë, ÔÈÎ_Êëèåíòà, Ìàòü, Îòåö, Ðîäñòâåííèêè, Ó÷¸ò_âðà÷à) values ('+
      #39+Create_client.Edit4.Text+#39','#39+Create_client.Edit5.Text+#39','#39+Create_client.Edit6.Text+#39','+
      #39+Create_client.Edit11.Text+#39','#39+Create_client.Edit12.Text+#39','#39+s+#39','+
      #39+KodC+#39','#39+KodM+#39','#39+KodO+#39','#39+KodR+#39','#39+KodD+#39')';
      ExecSQL;
      SQL.Text := 'SELECT @@identity as ID';
      Open;
      KodP:=FieldValues['ID'];
      SQL.Text:='UPDATE groups SET groups.Êîä=client.ParentID'''+
      'Where ParentID=:Êîä';
      Parameters.ParamByName('Êîä').Value:=KodP;
      ExecSQL;
туплю совсем так выдает ошибку параметр не найден

Добавлено через 5 минут
Вот это:
Delphi
1
 kod:=integer(Create_client.ComboBox2.Items.Objects[Create_client.ComboBox2.ItemIndex]);
даёт мне значение группы её, я могу вписать в parentID, но в гриде отображался только один клиент

по такому же принципу мне надо будет создавать и группы, т.к. к одной базе может относиться несколько групп

Добавлено через 22 минуты
Вот это:
Delphi
1
2
3
4
5
6
  SQL.Text:='INSERT INTO client( Òåëåôîí, Ýëåêòðîííàÿ_ïî÷òà, Äàòà_ðîæäåíèÿ,'+
      'Ïðè÷èíà, Äàòà_Âðåìÿ_ïðè¸ìà, Ïîë, ÔÈÎ_Êëèåíòà, Ìàòü, Îòåö, Ðîäñòâåííèêè, Ó÷¸ò_âðà÷à,[B]ParentID[/B]) values ('+
      #39+Create_client.Edit4.Text+#39','#39+Create_client.Edit5.Text+#39','#39+Create_client.Edit6.Text+#39','+
      #39+Create_client.Edit11.Text+#39','#39+Create_client.Edit12.Text+#39','#39+s+#39','+
      #39+KodC+#39','#39+KodM+#39','#39+KodO+#39','#39+KodR+#39','#39+KodD+#39','[B]#39+inttostr(kod)+#39'[/B])';
      ExecSQL;
даёт запись в БД о Группе к которой принадлежит клиент, но при выборе группы в комбобокс2 в дбгрид отображается только старый клиент, новый не появляется
0
1074 / 987 / 340
Регистрация: 07.08.2012
Сообщений: 2,790
04.12.2014, 09:10 29
Delphi
1
2
3
4
5
6
7
    SQL.Text:='INSERT INTO client( Телефон, Электронная_почта, Дата_рождения,'+
      'Причина, Дата_Время_приёма, Пол, ParentID, ФИО_Клиента, Мать, Отец, Родственники) values ('+
      #39+Create_client.Edit4.Text+#39','#39+Create_client.Edit5.Text+#39','#39+
      Create_client.Edit6.Text+#39','#39+Create_client.Edit11.Text+#39','#39+
      Create_client.Edit12.Text+#39','#39+s+#39','+IntTostr(kod)+','+
      IntToStr(KodS)+','+IntToStr(KodM)+','+IntToStr(KodO)+','+IntToStr(KodR)+','+')';
    ExecSQL;
Здесь вставлено, ранее пропущенное, значение kod (ид группы), которое берется из комбобокса2 выше. Больше ничего мудрить не надо
Повторюсь, если нужно добавить новую группу, то это делается в другом месте.

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

Обращаю внимание, что числовые значения не должны быть в кавычках, т.е. вместо символов #39, обрамляющих значение, числа в текст запроса передаются, преобразованные функцией IntToStr в строковое представление.
1
0 / 0 / 0
Регистрация: 08.06.2013
Сообщений: 70
04.12.2014, 09:25  [ТС] 30
Всё равно в гриде только один клиент, новый не добавился, в базе запись есть
0
1074 / 987 / 340
Регистрация: 07.08.2012
Сообщений: 2,790
04.12.2014, 09:28 31
И в чем вопрос?
Видимо, придется опять выкладывать проект.
0
0 / 0 / 0
Регистрация: 08.06.2013
Сообщений: 70
04.12.2014, 09:31  [ТС] 32
Выкладываю, может из-за того что я в схеме данных удалил все связи в access?
Вложения
Тип файла: zip Прога 2 (2).zip (4.31 Мб, 2 просмотров)
0
0 / 0 / 0
Регистрация: 08.06.2013
Сообщений: 70
04.12.2014, 09:34  [ТС] 33
Да кстати забыл сказать dbgrid находиться в выбрать клиента там же можно и базу и группу выбрать
0
04.12.2014, 09:34
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.12.2014, 09:34
Помогаю со студенческими работами здесь

Запрос из нескольких таблиц с категориями SQL Access 2007
Здравствуйте уважаемые посетители форума! Разрабатываю базу данных специфического кадрового учета...

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

Загрузка данных из excel в таблицу access
Добрый день! Раньше работала с sql server. И все там хорошо, пакеты интеграции, можно настроить...

Загрузка данных с листа в БД Access SQL
Здравствуйте, подскажите, каким образом можно загрузить данные из диапазона ячеек в базу данных...


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

Или воспользуйтесь поиском по форуму:
33
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru