Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Круглый стол
  
Правила КС
>> Настройки

Фильтр вопросов
>> Новые вопросы
отслеживать по
>> Новые ответы

Избранное

Страница вопросов
Поиск по КС


Специальные проекты:
>> К л ю к в а
>> Г о л о в о л о м к и

Вопрос №

Задать вопрос
Off-topic вопросы

Помощь

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  22:43[Войти] | [Зарегистрироваться]
Ответ на вопрос № 41081

27-03-2006 00:34
Кто знает подскажите !!!!!
есть БД Access в ней 2 Таблицы:
ФИО(главная) и Адрес(подчиненная)
Key(счетчик)|  Key1(счетчик)      связь Key-Key1
Фамилия    |  Город
имя        |  Улица
Отчество    |  Дом(квартира)
в Delphi есть форма на которой есть: DBGrid,
6 Edit-тов и кнопки "добавить" и "удалить"
Пользователь вводит в Editы данные нажимает на кнопку "Добавить"
и данные которые он ввел должны добавлятся в таблицы,и
отображаться в DBGride.
как это сделать? и как удалить текущую запись по кнопке "Удалить"?
к БД подключаюсь через ADOTable.
добавляю через ADOQuery запросом
по кнопке "добавить" пишу:


datamodule2.ADOQuery1.Close ;
datamodule2.ADOQuery1.SQL.Clear;
datamodule2.ADOQuery1.SQL.Add('insert into [ФИО] ([fldФамилия], [fldИмя],[fldОтчество])');
datamodule2.ADOQuery1.SQL.Add('values ('+chr(39)+Edit1.Text+chr(39)+','+chr(39)+Edit2.Text+chr(39)+','+chr(39)+Edit3.Text+chr(39)+','+chr(39)+');');
datamodule2.ADOQuery1.ExecSQL;
datamodule2.ADOQuery2.Close ;
datamodule2.ADOQuery2.SQL.Clear;
datamodule2.ADOQuery2.SQL.Add('insert into [Адрес] ([Город], [Улица],[Дом])');
datamodule2.ADOQuery2.SQL.Add('values ('+chr(39)+Edit7.Text+chr(39)+','+chr(39)+Edit8.Text+chr(39)+','+chr(39)+Edit9.Text+chr(39)+');');
datamodule2.ADOQuery2.ExecSQL;


Выдает ошибку "Размер поля недостаточен чтобы принять добавляемые поля"
как быть ???
все поля проверил! ввожу не более 10 символов .

[+] Добавить в избранные вопросы

Отслеживать ответы на этот вопрос по RSS

Ответы:


Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице.
Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.

28-03-2006 01:19 | Комментарий к предыдущим ответам
Честь и хвала, по истине самый терпеливый.

Это я вчера просто очень добрый был.
А вообще-то обычно я очень злой и раздражительный.
:-)

28-03-2006 00:28
2 Green.

Честь и хвала, по истине самый терпеливый.
Побольше таких.

С Уважением...

27-03-2006 23:38
работает СПАСИБО !
вот ещеб разобраться как !....


А что тут разбираться, все очень просто:
- Добавляем запись в первую таблицу, nil ставим потому что поле - счетчик и устанавливать его значение не нужно, оно заполнится автоматически

ADOTable1.AppendRecord([nil, Edit1.Text, Edit2.Text, Edit3.Text]);


- Запоминаем полученное значение счетчика в переменной

Key := ADOTable1.Fields[0].Value;


- Добавляем запись во вторую таблицу со ссылкой на ключ первой таблицы

ADOTable1.AppendRecord([Key, Edit7.Text, Edit8.Text, Edit8.Text]);


27-03-2006 15:15 | Сообщение от автора вопроса
Green
работает СПАСИБО !
вот ещеб разобраться как !....
всем спасибо!!!!!!!!!!

27-03-2006 15:06
ошибка та же !

Я что, ясновидящий? В какой строке?
Если в первой:

ADOTable1.TableName := 'ФИО';


то поставь перед ней Close вот так:

ADOTable1.Close;
ADOTable1.TableName := 'ФИО';


Ухожу спать. Завтра пиши...

27-03-2006 14:50 | Сообщение от автора вопроса
Green
ошибка та же !

27-03-2006 14:37
выдает ошибку 'ADOTable1: Cannot perform this operation on an open dataset'

"Невозможно выполнить эту операцию на открытом датасете"

Я же говорил, что код не тестировал :-(

После установки TableName надо открывать таблицу, а перед установкой - закрывать:

var
  Key: integer;
begin
  ADOTable1.TableName := 'ФИО';
  ADOTable1.Open; // <<<<<
  ADOTable1.AppendRecord([nil, Edit1.Text, Edit2.Text, Edit3.Text]);
  Key := ADOTable1.Fields[0].Value;
  ADOTable1.Close; // <<<<<
  ADOTable1.TableName := 'Адрес';
  ADOTable1.Open; // <<<<<
  ADOTable1.AppendRecord([Key, Edit7.Text, Edit8.Text, Edit8.Text]);
  ADOTable1.Close; // <<<<<
  ADOQuery1.Close;
  ADOQuery1.Open;
end;


Если я опять чего-то не забыл :-(

27-03-2006 14:30 | Комментарий к предыдущим ответам
по указанному вами адресу я был!
там рассматривается пример с телеф.справочником!
а как вы заметили похожего там нет.

Поля подстановок там есть? Реализация есть? Две таблицы есть? Что еще нужно, чтобы понять механизм работы???

27-03-2006 14:20 | Сообщение от автора вопроса
Сабир Сафаров
по указанному вами адресу я был!
там рассматривается пример с телеф.справочником!
а как вы заметили похожего там нет.

27-03-2006 13:51 | Сообщение от автора вопроса
Green
выдает ошибку 'ADOTable1: Cannot perform this operation on an open dataset'
установил связь Key-Key1.
что я неправильно делаю ?

27-03-2006 13:07
to Сабир Сафаров:

Разбейте свою таблицу еще примерно на 5-6 и тогда с целостностью все будет ОК :o)

Не надо смеяться над преподом. Акцесс, конечно, это несерьезно, но вот в MS SQL можно разбить таблицу на несколько более мелких и хранить их физически на разных серверах. В этом случае при ядерном взрыве вероятность полной потери данных сильно уменьшается.

А препод-то не так прост!

27-03-2006 12:59
а я и не говорил что надо по две строки для одной фамилии выводить!
это типа для целостности данных сказал препод!


Вот он, момент истины! Через 11 часов обсуждения я начал хоть что-то понимать!

Ну что сказать? Очевидно, что бессмысленно делать две таблицы, если одна фамилия никогда не будет содержать два адреса. Но как объяснить это преподу? Судя по его знаниям в области целостности данных - никак :-(
Остается только сделать так, как хочет препод.

Итак, таблицы:
[ФИО]: Key (счетчик), Фамилия, Имя, Отчество
[Адрес] Key1 (ЧИСЛОВОЕ), Город, Улица, Дом

Еще раз обращаю внимание - поле Key1 в таблице [Адрес] ЧИСЛОВОЕ, а не счетчик!

var
  Key: integer;
begin
// ADOTable1 - специально для операций с таблицами
  ADOTable1.TableName := 'ФИО';
// Добавляем запись в таблицу [ФИО]
  ADOTable1.AppendRecord([nil, Edit1.Text, Edit2.Text, Edit3.Text]);
// Запоминаем значение счетчика
  Key := ADOTable1.Fields[0].Value;
  ADOTable1.TableName := 'Адрес';
// Добавляем запись в таблицу [Адрес], в качестве поля Key1 используем
// значение счетчика из таблицы [ФИО], чтобы записи в таблицах были связаны
  ADOTable1.AppendRecord([Key, Edit7.Text, Edit8.Text, Edit8.Text]);
// ADOQuery связан содержит запрос, объединяющий таблицы, и связан с гридом
// или можно использовать другой ADOTable - без разницы.
// Переоткрываем его, чтобы увидеть вставленные записи.
  ADOQuery1.Close;
  ADOQuery1.Open;
end;


Код не проверял, возможны мелкие неточности, но суть верна!

27-03-2006 12:11 | Комментарий к предыдущим ответам
это типа для целостности данных
Сначала надо нагородить, а затем побеспокоиться о целостности  - ну чтобы задача простой не казалась.
Разбейте свою таблицу еще примерно на 5-6 и тогда с целостностью все будет ОК :o)
Давайте тогда сначала (препологается, что вы уже почитали книжки по совету уважаемого Green-а):
1) Построение БД всегда начинается с изучения предметной области.
У вас есть студенты, которые где-то живут. Неужели вы изначально считаете, что один студент может жить в нескольких местах? Это необоснованное усложнение задачи.
Определимся с зависимостями. Реальная зависимость многие к одному есть между студентами и городом. В одном городе может проживать несколько студентов, но один и тот же студент не может проживать в нескольких городах. Поэтому, чтобы избежать так называемых аномалий вставки, изменения и удаления города необходимо вынести в отдельную таблицу. Пусть это таблица City(id,name). Тогда в основной таблице вы должны вместо поля "город" вставить внешний ключ - допустим idcity. Структура вашей таблицы примет вид: Student(ID, Familiya, Imya, Otchestvo, Address, idсity, Ulica, Dom).
Где поле ID - целое, автоинкрементное, а поле idсity - целое, но не автоинкрементное.

2) Реализация в Делфи: В любой книге про Делфи, где хоть поверхностно затрагивается создание приложений для работы с базами, рассматривается подробно ваш случай. Объяснять на форуме как это делается - проблематично (Получиться целая глава книги). Если у вас нет под рукой книг, воспользуйтесь электронными вариантами (например здесь http://podgoretsky.com/ftp/Docs/Delphi).

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

И самое главное поймите - на форумах за вас никто программировать не будет. Здесь могут подсказать, навести на мысль, кинуть ссылочку, но предоставить готовую программу - извините.

На сем заканчиваю...

27-03-2006 11:39 | Сообщение от автора вопроса
to Green
а я и не говорил что надо по две строки для одной фамилии выводить!
это типа для целостности данных сказал препод!

27-03-2006 11:36 | Сообщение от автора вопроса
to Сабир Сафаров
не работает!
to Green
структуру таблицы и текст программы почему то не дали :-((((
:-))))))))))
это задание дал препод, за неделю сказал зделать!

27-03-2006 11:16
да задача так поставленна чтоб данные находились в 2-х и более таблицах!

Ого! Детальная постановка задачи. Количество гридов равное единице тоже в задаче поставлено? А структура таблицы и текст программы случайно в задаче не поставлены - это сильно бы упростило проблему? :-)

А чем обоснована такая постановка задачи? Почему не в одной таблице? Или это лабораторная работа или заказчик шибко грамотный.

Все это, конечно, интересно, но не надо быть программистом, чтобы понять, что вывести в одной строке два адреса проблематично, вывести две одинаковые фамилии в двух строках - тоже криво. Сначала надо бы с интерфейсом разобраться, а потом уже за код браться (стихи опять получились).

27-03-2006 11:07 | Комментарий к предыдущим ответам
Понятно - это какая-то фишка акцессовская. У запроса есть имя - для меня это чудо.
Так, тогда вопрос по другому - вы сделали так как написал Master_NN: создали пару таблиц с полями, которые он написал и т.д. - и не работает?

27-03-2006 10:44 | Сообщение от автора вопроса
да задача так поставленна чтоб данные находились в 2-х и более таблицах!

27-03-2006 10:19
Green а в чем проблема то ? ну и что что DBGrid один!

Проблема не в том, что грид один, а в том что его не столько же, сколько таблиц. Как можно вывести одним запросом в один грид данные на людей, если у них по нескольку адресов? А если у них по одному адресу, то зачем тогда две таблицы? Налицо фигня :-(

27-03-2006 09:13 | Сообщение от автора вопроса
Запрос построил мастером Access, добавил поля которые надо отображать и все!
в ADTable в свойстве TableName указал имя этого запроса !
DataSource настроил на ADOTable, DBGrid на DATASource !
ADOTable.Active:=true.
вот и все !
это что новость ?

27-03-2006 09:02
DBGrid->DataSource->ADOTable ->Запрос
Это новая методика или просто ЧУДО?
Что вы прописываете в запросе? Что указываете в настройках AdoTable? На какую таблицу настраиваете?

27-03-2006 08:56 | Сообщение от автора вопроса
Green а в чем проблема то ? ну и что что DBGrid один!

27-03-2006 08:44
to _MaSteR_NN_:

Создайте ребята на форме 150 кнопок... Нет, не то.
Какой вопрос - такой ответ. При добавлении записей запросом тебе тоже придется 150 кнопок делать. Только вряд ли кто-то будет твою идею на практике использовать.

to Леонид Голиков:

DBGrid один
Интересно. Грид один, а таблицы две?
Срочно книгу в руки - и на диван!

27-03-2006 08:40 | Сообщение от автора вопроса
не через ADOTable  а через DBGrid->DataSource->ADOTable ->Запрос

27-03-2006 08:38 | Сообщение от автора вопроса
не через ADOTable  а через DataSource.

27-03-2006 08:36
создал запрос на отображение данных из 2-х таблиц,и этот запрос прицепил к DBGrid-у через ADOTable.
ММММ-да. Опишите подробней, интересно

27-03-2006 08:35
2 Green
Ай молодца.
Да хоть десять:
ADOTable1.AppendRecord([Null, Edit1.Text, Edit2.Text, Edit3.Text]);
ADOTable2.AppendRecord([ADOTable1.Fields[0].Value, Edit7.Text, Edit8.Text, Edit8.Text]);
//...еще восемь раз
ADOTable2.AppendRecord([ADOTable1.Fields[0].Value, Edit7.Text, Edit8.Text, Edit8.Text]);


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


Создайте ребята на форме 150 кнопок, и в каждой из них прибавьте по одному
ADOTable2.AppendRecord([ADOTable1.Fields[0].Value, Edit7.Text, Edit8.Text, Edit8.Text]);
В Итоге первая кнопка создаст одну запись в таблице Address
вторая кнопка - 2 записи.
{Ещё 147 кнопок}
150-ая создасть .... ну понимаете.
Нет, не то.



2  Леонид Голиков

Вы уже создали... ?
Начали.
Есть одна таблица FIO с полями (FioID(автоикр.), Familiya, Imya, Otchestvo)
Вторая таблица Address с полями (AddressID (автоикр.), Address, Gorod, Ulica, Dom,  FioID int(ключ из таблицы FIO, не Автоинкрементный)).



С Уважением...


27-03-2006 08:29 | Сообщение от автора вопроса
Green
DBGrid один.
в Accesse создал запрос на отображение данных из 2-х таблиц,и этот запрос прицепил к DBGrid-у через ADOTable.
но с добавлением все же проблема остается!

27-03-2006 08:27
to Леонид Голиков:

выдает ошибку 'ADOQuery1: Field 'FioID' not Found'

Field - поле, not found - не найдено.

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

27-03-2006 08:23
to _MaSteR_NN_:

Если я захочу добавить Вторую запись в таблицу Address то что я получу использовав ваш вариант?
Да хоть десять:

ADOTable1.AppendRecord([Null, Edit1.Text, Edit2.Text, Edit3.Text]);
ADOTable2.AppendRecord([ADOTable1.Fields[0].Value, Edit7.Text, Edit8.Text, Edit8.Text]);
//...еще восемь раз
ADOTable2.AppendRecord([ADOTable1.Fields[0].Value, Edit7.Text, Edit8.Text, Edit8.Text]);


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

27-03-2006 08:17 | Сообщение от автора вопроса
_MaSteR_NN_
выдает ошибку 'ADOQuery1: Field 'FioID' not Found'
все проверил ,но нехочет и все тут :-(

27-03-2006 08:15
Green, Если вы не заметили, то это была всего лишь идея...
Нет, не заметил. По объему кода это тянет больше на исчерпывающее решение, чем на просто идею.

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

Если вы пытаетесь просто придираться, то другое дело...
Я не придираюсь. Просто мое решение очень простое и наглядное, и я не понимаю зачем делать сложно, когда можно просто?

А Сабир Сафаров совершенно прав. Во-первых, автору надо теорию сначала почитать, а то таких вопросов можно миллион назадавать. А во-вторых, для этой задачи и правда подошла бы одна таблица. Адрес у человека все равно как правило один, а что программа не для китайцев - это мы уже выяснили :-)

27-03-2006 08:11 | Комментарий к предыдущим ответам
to Master_NN:Вывод – используйте собственное ключевое поле во всех без исключения таблицах. Даже если Вам кажется, что без него можно обойтись.
Спорное утверждение, очень спорное...
Пример: Есть таблица Table1(id,name) и таблица Table2(id,name). Между ними существует связь M:N. Вводим третью таблицу Table1_Table2(idTable1,idTable2). Никаких дополнительных полей в ней исходя из предметной области не требуется. Достаточно ввести составной первичный ключ (idTable1,idTable2), чтобы на уровне базы контролировать дублирующиеся строки, или даже лучше прописать триггер, в котором перед вставкой проверять отсутствие необходимой строки.
Послушаем ваш совет и подсчитаем, сколько мы можем сэкономить места если обойдемся триггером. Представьте, что у вас в первой таблице 10^6 записей, во второй 10^6 записей. Получается что если вводить дополнительный первичный ключ, то он должен быть 8 байтовым (bigint или как-там по другому) - итого вы откусываете на винте 8*10^12 байт. Это конечно все очень утрировано (на физическом уровне в БД все сложнее) но все же АЙ-АЙ-АЙ. Так нельзя.
Вывод: все сложнее.

27-03-2006 07:59
2Green

Если я захочу добавить Вторую запись в таблицу Address то что я получу использовав ваш вариант?
ADOTable1.AppendRecord([Null, Edit1.Text, Edit2.Text, Edit3.Text]);
ADOTable2.AppendRecord([ADOTable1.Fields[0].Value, Edit7.Text, Edit8.Text, Edit8.Text]);

А теперь прочитайте что было предложено...

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

.....

теперь в таблице Address есть запись относящаяся к выбранной в таблице FIO.

......

Теперь должен получиться результат. 2 Грида. Один отображает записи таблицы FIO, а другой Address'a .

C Уважением...

27-03-2006 07:45
Первый раз вижу, чтобы закрывали запрос в гриде, чтобы в него запись добавить!!!
Green, Если вы не заметили, то это была всего лишь идея... Есть ещё такое понятие, как тэмповый Query, или отдельный исполняемый Query, в котором динамически можно отрабатывать все запросы, я не прав? Ещё лучше бы использовать транзакции на добавление итд, чем описанный вами  AppendRecord. Уж больно я сомневаюсь что AppendRecord лучшее решение. Если вы пытаетесь просто придираться, то другое дело... Удачи.

С Уважением...

27-03-2006 07:43 | Комментарий к предыдущим ответам
ничего непомогает!
я уже 3 дня над этой задачей сижу !

Вы потратите еще больше своего времени, если не разберетесь капитально в структуре реляционных баз (если это конечно вам нужно).  Как правильно заметили Green и Master_NN, у вас неправильная структура данных,а ее уже никакими ухищрениями не исправишь.
Действительно, зачем городить весь этот огород с двумя (или тремя) таблицами, их связыванием и т.д. если у вас между ними скорее всего отношение один к одному? Зато "город" является просто полем, а не вынесено в отдельную таблицу. Есть такое замечательное правило в БД: "каждый факт в одном месте" - от него и танцуйте.
PS Много хороших, доступным языком написанных книг на citforum.ru
Настойчиво рекомендую - посмотрите, сэкономите свое время

27-03-2006 07:37
выдает ошибку 'Field 'Key1' kannot be modified'

Если ошибка в первом AppendRecord, то надо поставить nil вместо Null.
Если во втором, то причина в том, что у тебя поле Key1 - счетчик, а надо число.

27-03-2006 07:33
to Леонид Голиков:

ничего непомогает!
я уже 3 дня над этой задачей сижу !
мож кто скинет пример рабочий кому не жалко!


Когда я заменил Null на nil (стихи), то у меня все заработало.
Код из двух строк, которые я написал. Напиши свой код, укажи строку, которая выдает ошибку и какая сейчас структура таблиц. Какие компоненты ADOTable с какими таблицами связаны? Убрал ли ты счетчик из второй таблицы?

to _MaSteR_NN_:

Первый раз вижу, чтобы закрывали запрос в гриде, чтобы в него запись добавить!!!
Особенно прикольно будет выглядеть, когда при возникновении ошибки записи запрос закроется и не откроется :-(
И по-моему код из двух строк немного проще, чем из 20, тем более, что при добавлении записи курсор не будет перемещаться на начало грида.

Еще раз повторяю - код с AppendRecord - рабочий. Просто надо разобраться со структурой БД и с тем, что за интерфейс делает автор вопроса. Не усложняйте код там где это не нужно, он сам где надо усложнится :-)

27-03-2006 06:53
Начали.
Есть одна таблица FIO с полями (FioID(автоикр.), Familiya, Imya, Otchestvo)
Вторая таблица Address с полями (AddressID (автоикр.), Address, Gorod, Ulica, Dom,  FioID int(ключ из таблицы FIO, не Автоинкрементный)).

Вставляем данные в таблицу FIO

  ADOQuery1.Close;  //Закрываем таблицу
  ADOQuery1.SQL.Text := 'Insert into FIO(Familiya, Imya, Otchestvo) values (:Familiya, :Imya, :Otchestvo) '; // Запрос
ADOQuery1.Parameters.ParamByName('Familiya').Value := Edit1.Text;  //
ADOQuery1.Parameters.ParamByName('Imya').Value := Edit2.Text;  //
ADOQuery1.Parameters.ParamByName('Otchestvo').Value := Edit3.Text;  //параметр
  ADOQuery1.ExecSQL;  // запрос на выполнение
  ADOQuery1.Close;
  ADOQuery1.SQL.Text :=  'Select * from FIO'; // возвращаемый результат
  ADOQuery1.Open;



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

  ADOQuery1.Close;  //Закрываем таблицу
  ADOQuery2.SQL.Text := 'Insert into Address(Address, Gorod, Ulica, Dom,  FioID) values (:Address, :Gorod, :Ulica, :Dom,  :FioID ) '; // Запрос
ADOQuery2.Parameters.ParamByName('Address').Value := Edit4.Text;  //
ADOQuery2.Parameters.ParamByName('Gorod').Value := Edit5.Text;  //
ADOQuery2.Parameters.ParamByName('Ulica').Value := Edit6.Text;  //
ADOQuery2.Parameters.ParamByName('Dom').Value := Edit7.Text;  //
ADOQuery2.Parameters.ParamByName('FioID ').Value := ADOQuery1.FieldByName('FioID').AsInteger;  //
  ADOQuery2.ExecSQL;  // запрос на выполнение
  ADOQuery2.Close;
  ADOQuery2.SQL.Text :=  'Select * from Address Where FioID = '+ADOQuery1.FieldByName('FioID').Value; 
  ADOQuery2.Open;



теперь в таблице Address есть запись относящаяся к выбранной в таблице FIO.

Динамически выбирать записи из таблицы Address можно поместив в DataSource(AdoQuery1) onChange

  ADOQuery2.Close;
  ADOQuery2.SQL.Text :=  'Select * from Address Where FioID = '+ADOQuery1.FieldByName('FioID').Value; 
  ADOQuery2.Open;



Теперь должен получиться результат. 2 Грида. Один отображает записи таблицы FIO, а другой Address'a .


C Уважением...

27-03-2006 06:30 | Сообщение от автора вопроса
ничего непомогает!
я уже 3 дня над этой задачей сижу !
мож кто скинет пример рабочий кому не жалко!

27-03-2006 06:28
выдает ошибку 'Field 'Key1' kannot be modified'

Всё верно!

ADOTable1.AppendRecord([Null, Edit1.Text, Edit2.Text, Edit3.Text]);
ADOTable2.AppendRecord([ADOTable1.Fields[0].Value, Edit7.Text, Edit8.Text, Edit8.Text]);
выдает ошибку 'Field 'Key1' kannot be modified'

Вы делаете AppendRecord и как я понял в поле Key1 вбиваете Null, вот вам сервер и отвечает...

Делайте запросом с параметрами. Пример я уже привёл.

С Уважением...

27-03-2006 06:08
выдает ошибку 'Field 'Key1' kannot be modified'

Код не проверял, поэтому возможны косяки :-(

Поставь вместо Null - nil

27-03-2006 05:56 | Сообщение от автора вопроса
поле Key1 счетчик в первой таблице (ФИО)

27-03-2006 05:52
как в третьей таблице указать отношения менжду 1-й и 2-й ???

Тогда поле Key1 надо оставить типа "счётчик" и сделать третью таблицу с полями Key и Key1. После вставки записей в таблицы [ФИО] и [Адрес] новые значения счётчиков вставляются соответственно в поля Key и Key1 третьей таблицы. Но это только если нужно обеспечить отношение "многие-ко-многим". Как я уже говорил, если программа не для китайцев, достаточно двух таблиц :-)

27-03-2006 05:47
2 Green
А собственно зачем?
Во-первых
Как минимум "правило хорошего тона" в построении баз данных...
Во-вторых
Ключевое поле – это такое поле (или набор полей) по содержимому которого можно однозначно идентифицировать запись таблицы. Т.е. по значению ключевого поля всегда однозначно можно сказать о какой записи идет речь и не может существовать 2 записей с одинаковыми значениями ключевого поля.

На первый взгляд, вопрос может показаться странным. Разве можно без ключевого поля? Оказывается, в некоторых случаях можно.
Например, для организации связи много-ко-многим стандартным способом является создание таблицы-посредника. Что имеется в виду?
Допустим, у Вас есть список контрагентов и список банков. Разумеется, один и тот же контрагент может иметь счет в нескольких банках. Но верно и обратное – один банк работает с несколькими контрагентами. В этом случае Вы не можете сделать внешний ключ банка в таблице контрагента или внешний ключ контрагента в таблице банков. Вам необходимо ввести таблицу-посредник, которая будет хранить в себе внешний ключ банка и внешний ключ контрагента.



При такой организации, каждая запись в этой таблице посреднике однозначно идентифицируется парой значений: код контрагента-код банка. Поэтому возникает искушение не вводить еще одно поле для суррогатного ключа этой таблицы-посредника.
Однако я настоятельно рекомендовал бы Вам вводить-таки собственное ключевое поле для всех таблиц базы данных. Почему? Ну, потому, что любая программа имеет «привычку» развиваться.



Если вернуться к примеру с контрагентами и банками, то легко заметить, что я обошел вниманием тот момент, что один контрагент может иметь несколько счетов в одном и том же банке. Этот самый реквизит (счет контрагента в банке) невозможно прицепить ни к банку, ни к контрагенту. Но он очень удачно подходит к этой таблице-посреднику. Если бы для идентификации записи в этой таблице Вы опирались бы на пару: код банка – код контрагента, то Вам пришлось бы серьезно переделывать значительную часть программы. А в случае существования собственного кода записи никаких проблем. Ну, добавили еще одно поле, ну и что?



В данном случае я рассмотрел достаточно очевидный случай, но зачастую кажется, что по-другому быть не может и уж вот здесь-то собственный идентификатор записи не нужен. Не обольщайтесь. Если Вам кажется, что чего-то не может быть – это всего-лишь значит, что Вы чего-то не знаете.



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


С Уважением...

27-03-2006 05:47
выдает ошибку 'Field 'Key1' kannot be modified'

Поле типа "счётчик" нельзя изменять. Если это поле из таблицы [Адрес], его надо сделать числовым.

27-03-2006 05:42 | Сообщение от автора вопроса
делаю без запроса
ADOTable1.AppendRecord([Null, Edit1.Text, Edit2.Text, Edit3.Text]);
ADOTable2.AppendRecord([ADOTable1.Fields[0].Value, Edit7.Text, Edit8.Text, Edit8.Text]);
выдает ошибку 'Field 'Key1' kannot be modified'
поле Key1 -счетчик(ключевое) в таблице ФИО.
в чем проблема ??
открываю Access в ФИО все добавил а 2-я табл. пустая !
и как в третьей таблице указать отношения менжду 1-й и 2-й ???

27-03-2006 05:34 | Комментарий к предыдущим ответам
to _MaSteR_NN_:

а во второй таблице нужно ключевое поле или нет ?
Нужен. Можно Автоинкрементное.


А собственно зачем?

27-03-2006 05:30
MasterID в первой таблице счетчик.(ключевое) правильно ?
Абсолютно.

MasterID во второй таблице число (совпадения допускаются так ?)
ага, допускаются, и даже обязательно. А заполняться они будут по мере заполнения таблицы Detail. То есть это номер ФИО к которому будет относиться Detail информация. (а как её выбирать я уже показывал.)

а во второй таблице нужно ключевое поле или нет ?
Нужен. Можно Автоинкрементное.

С Уважением...

27-03-2006 05:28
а что знаит автоинкрементные ???

В Акцессе это называется "счётчик". Если ты хочешь сделать связь "многие-ко-многим" (фамилия может иметь много адресов, адрес может иметь много фамилий), то у тебя должны быть две таблицы с ключевыми полями - счётчиками и третья таблица с двумя полями (Key, Key1), которая будет хранить отношения между первыми двумя таблицами.
Если ты хочешь сделать связь "один-ко-многим" (на одну фамилию много адресов), то во второй таблице ключевое поле должно быть не "счётчик", а "числовой". Значение этого поля должно заполняться не автоматически, как сделано у тебя сейчас, а вручную тем значением, которое было сгенерировано счётчиком при вставке строки в первую таблицу.
Если не использовать запросы, то код сильно упрощается, примерно так:
ADOTable1.AppendRecord([Null, Edit1.Text, Edit2.Text, Edit3.Text]);
ADOTable2.AppendRecord([ADOTable1.Fields[0].Value, Edit7.Text, Edit8.Text, Edit8.Text]);

27-03-2006 05:26
автоинкрементное поле это счетчик что ли ?
Именно... и увеличиваться он будет на указанную величину.

Вот пример с запросом с использованием параметров.

procedure TForm1.Button1Click(Sender: TObject);
Begin

TRY
  ADOConnection1.BeginTrans;
  ADOQuery1.Close;  //Закрываем таблицу
  ADOQuery1.SQL.Text := 'Insert into ФИО(Name) values (:ID, :Name) '; // Запрос
ADOQuery1.Parameters.ParamByName('Name').Value := Edit1.Text;  // параметр
  ADOQuery1.ExecSQL;  // запрос на выполнение
  ADOQuery1.Close;
  ADOQuery1.SQL.Text :=  'Select * from ФИО; // возвращаемый результат
  ADOQuery1.Open;
  ADOConnection1.CommitTrans;  // применить действия
EXCEPT
  ADOConnection1.RollbackTrans;  // в случае неудачи откатить транзакцию
END;

end;

С Уважением...

27-03-2006 05:23 | Сообщение от автора вопроса
MasterID в первой таблице счетчик.(ключевое) правильно ?
MasterID во второй таблице число (совпадения допускаются так ?)
а во второй таблице нужно ключевое поле или нет ?

27-03-2006 05:19 | Сообщение от автора вопроса
Спасибо Уважаемый !
автоинкрементное поле это счетчик что ли ?

27-03-2006 05:15 | Сообщение от автора вопроса
а как без запроса ????
мне ж в разные таблицы надо добавлять ?

27-03-2006 05:10
Привет!
2 Леонид Голиков
а что знаит автоинкрементные ??? и на что это влияет ?
Это значит что при каждой вставки записи в таблицу автоинкрементное поле будет увеличиваться автоматически(по умолчанию на единицу.)
Так вот. Если есть две таблицы, которые должны быть связаны между собой, то это означает что они должныы быть связаны по какому-нибудь полю.
Например.
есть таблица Master (MasterID {может быть автоинкрементным}, MasterName)
и есть таблица Detail (DetailID, DetailName, MasterID{Вот по этому полю они и будут связаны} )
Например, при выборке, нам нужно что бы в гриде показывались записи которые относятся к выбранному полю из таблицы Master. Тогда просто делаете запрос

SELECT * FROM Detail WHERE Detail.MasterID = Master.MasterID



Вот таким спобом и связываются таблицы, и эта связь называется один-ко-многим. То есть на одну Master запись будут добавляться записи в Detail, относящиеся к  Master по ключу MasterID ...
Так будет и в вашем случае, где к таблице ФИО будет относиться таблица Адрес. То есть на одну запись из Таблицы ФИО можно будет повесить несколько адресов.

Исходя из этого у вас в таблице Адрес должно быть связующее поле из таблицы ФИО.

С Уважением...

27-03-2006 04:47 | Сообщение от автора вопроса
а что знаит автоинкрементные ??? и на что это влияет ?

27-03-2006 04:28
Перечитал еще раз внимательно вопрос: есть БД Access в ней 2 Таблицы

Как же они связаны, если нет третьей таблицы, а оба ключевых поля автоинкрементные? Похоже они связаны только в мыслях автора вопроса, но для Дельфи этого недостаточно :-)
Нужно, чтобы поле Key1 было целое (не счетчик!) и ссылалось на Key.

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

27-03-2006 04:19
Судя по тексту вопроса существует еще третья таблица: Key(счетчик)| Key1(счетчик) связь Key-Key1
В нее же наверное тоже надо что-то добавить?

А зачем вся эта возня с запросами? Не проще ли одной строкой - AppendRecord

27-03-2006 04:03 | Вопрос к автору: запрос дополнительной информации
Поле key у вас автоинкрементное? Как вы узнаете что проставлять в поле key1? Т.е. из приведенного вами кода непонятно как вы осуществляете связывание при вставке. Или вы что-то не дописали, или ошибочка...
ЗЫ Попробуйте замечательные клавишы F7,F8...

27-03-2006 03:22 | Сообщение от автора вопроса
да проблема в том что он добавляет запись только в таблицу ФИО ! а во вторая остается пустая !

27-03-2006 01:33
В вашем случае данные в гриде надо обновить. Т.е. после вставки или удаления, сделать для датасета, который отображает ваш грид Requery.
to Green: "Что, есть люди, у которых два адреса? Или слишком много людей живут в одной квартире (программа для китайцев)". Например, студенты (почти как китайцы) - у них есть два адреса - домашний и временный в общаге. И в общаге в комнате может жить много студентов.

27-03-2006 00:57
Во-первых, зачем две таблицы для людей и для адресов? Что, есть люди, у которых два адреса? Или слишком много людей живут в одной квартире (программа для китайцев) :-)))

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

datamodule2.ADOQuery1.SQL.Add('values ('+chr(39)+Edit1.Text+chr(39)+','+chr(39)+Edit2.Text+chr(39)+','+chr(39)+Edit3.Text+chr(39)+','+chr(39)+');');


Используй либо параметризированные запросы, либо:

datamodule2.ADOQuery1.SQL.Add(Format('insert into [ФИО] ([fldФамилия], [fldИмя], [fldОтчество]) values (%s, %s, %s)', [QuotedStr(Edit1.Text), QuotedStr(Edit2.Text), QuotedStr(Edit3.Text)]));



В чем проблема с добавлением и удалением? См. хелп: AppendRecord method (TDataSet), InsertRecord method (TDataSet), Delete method (TDataSet).

Добавьте свое cообщение

Вашe имя:  [Войти]
Ваш адрес (e-mail):На Королевстве все адреса защищаются от спам-роботов
контрольный вопрос:
Жили у бабуси два веселых гуся. Один белый, другой КАКОЙ?
в качестве ответа на вопрос или загадку следует давать только одно слово в именительном падеже и именно в такой форме, как оно используется в оригинале.
Надоело отвечать на странные вопросы? Зарегистрируйтесь на сайте.
Тип сообщения:
Текст:
Жирный шрифт  Наклонный шрифт  Подчеркнутый шрифт  Выравнивание по центру  Список  Заголовок  Разделительная линия  Код  Маленький шрифт  Крупный шрифт  Цитирование блока текста  Строчное цитирование
  • вопрос Круглого стола № XXX

  • вопрос № YYY в тесте № XXX Рыцарской Квинтаны

  • сообщение № YYY в теме № XXX Базарной площади
  • обсуждение темы № YYY Базарной площади
  •  
     Правила оформления сообщений на Королевстве

    Страница избранных вопросов Круглого стола.
      
    Время на сайте: GMT минус 5 часов

    Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
    Функция может не работать в некоторых версиях броузеров.

    Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
    Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

     
    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

    Яндекс цитирования