Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > БД в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.03.2012, 07:28   #1
Rin
Негодник
Форумчанин
 
Аватар для Rin
 
Регистрация: 10.11.2009
Сообщений: 880
По умолчанию Как добавить новую запись в ADOTable, не используя DBNavigator?

Здравствуйте.
База Access. Подключаюсь через ADOConnection.
Есть родительская таблица CODE_FIO_worker с полями: Code: счётчик и FIO: строка; так же есть дочерняя таблица CODE_PHOTO с полями: CODE: счётчик и PHOTO: OLE-поле.
Для таблиц настроил связи через MasterSource и MasterField (CODE_FIO_worker.CODE-->CODE_PHOTO.CODE).

Пытаюсь добавить в CODE_PHOTO новую запись таким образом:
Код:
// добавление новой записи в CODE_PHOTO посредством SQL-запроса
SQL_ZAPROS.SQL.Clear;
    SQL_ZAPROS.SQL.Text:='INSERT INTO CODE_PHOTO '+
    '(CODE) VALUES ("'
    +Edit1.Text+'");';
    SQL_ZAPROS.ExecSQL;
    DataModule3.T_CODE_PHOTO.Close;
    DataModule3.T_CODE_PHOTO.open;

// переходим на последнюю запись 
    DataModule3.T_CODE_PHOTO.Last;

// тут добавляем в новую запись картинку/blob/OLE 
// если есть путь к файлу, то выполнить
if way<>'' then
    begin
      Img := TImage.Create(nil);
      Img.Picture.LoadFromFile(way);
      if Assigned(Img.Picture.Graphic) and (not Img.Picture.Graphic.Empty) then
      begin
        MemStream := TMemoryStream.Create;
        try
        Img.Picture.Graphic.SaveToStream(MemStream);
      {если использовать  DataModule3.T_CODE_PHOTO.Insert;
        то получаю ошибку "поле CODE не может было отредактировано. Это и понятно. Ведь CODE - счётчик.
         }
        DataModule3.T_CODE_PHOTO.Edit; 
      TBlobField(DataModule3.T_CODE_PHOTO.FieldByName('PHOTO')).LoadFromStream(MemStream);
        DataModule3.T_CODE_PHOTO.Post;
        finally
        MemStream.Free;
      end;
      Img.Free;
      end;
    end;

Но вместо новой N записи редактируется самая первая запись.
Попытался глянуть число записей в CODE_PHOTO
Код:
     i:=DataModule3.T_CODE_PHOTO.RecordCount;
Говорит, что там одна запись, хотя там 2 с заполненными OLE-полями и одна с пустым OLE.

И вот спрашивается, как добавить новую запись в дочернюю таблицу CODE_PHOTO?
Заранее благодарен за любую помощь.
Если помог, проси поставить минус. Будь оригинален!
Rin вне форума Ответить с цитированием
Старый 14.03.2012, 10:28   #2
vovk
!=
Участник клуба
 
Аватар для vovk
 
Регистрация: 08.09.2008
Сообщений: 1,751
По умолчанию

Честно логику не понял, зачем поле CODE = счётчик ?
скорее это должен быть внешний ключ,

почему просто запросом не добавить сразу с Фото??

Код:
if way<>'' then
    begin
      Img := TImage.Create(nil);
      Img.Picture.LoadFromFile(way);
      if Assigned(Img.Picture.Graphic) and (not Img.Picture.Graphic.Empty) then
      begin
        MemStream := TMemoryStream.Create;
        try
        Img.Picture.Graphic.SaveToStream(MemStream);
 
      SQL_ZAPROS.SQL.Clear;
    SQL_ZAPROS.SQL.Text:='INSERT INTO CODE_PHOTO (CODE,PHOTO) VALUES (:code_,:img)';
    SQL_ZAPROS.Parameters.ParamByName('code_').Value:=strtoint(edit1.text);
    SQL_ZAPROS.Parameters.ParamByName('img').LoadFromStream(MemStream,ftBlob);
      SQL_ZAPROS.ExecSQL;
  
    DataModule3.T_CODE_PHOTO.Close;
    DataModule3.T_CODE_PHOTO.open;
        finally
        MemStream.Free;
      end;
      Img.Free;
      end;
    end;
и запись у вас скорее всего 1, ведь у вас таблицы связаны, поэтому в Тдатасет должны содержатся только связанные записи.
Это при условии что я правильно понял.

Последний раз редактировалось vovk; 14.03.2012 в 15:25.
vovk вне форума Ответить с цитированием
Старый 14.03.2012, 13:46   #3
Rin
Негодник
Форумчанин
 
Аватар для Rin
 
Регистрация: 10.11.2009
Сообщений: 880
По умолчанию

Спасибо, Vovk, что откликнулись.
В этом коде должно быть code_ или code?
Код:
SQL_ZAPROS.SQL.Text:='INSERT INTO CODE_PHOTO (CODE,PHOTO) VALUES (:code,:img)';
    SQL_ZAPROS.Parameters.ParamByName('code_').Value:=strtoint(edit1.text);
А так же выдаёт ошибку: "Project Project1.exe raised exception class EConvertError with message "значение поиска" is not a valid integer value" .
Скорей всего ругается на параметрическую переменную code, у которой DataType=ftInteger (при выставлении ftAutoInc значение само меняется на ftInteger). А если написать так -
Код:
        SQL_ZAPROS.Parameters.ParamByName('code').DataType:=ftAutoInc;
-, то компилятор ругает меня так:
"Project Project1.exe raised exception class EDataBaseError with message 'SQL_ZAPROSarameter 'code' not found"

Цитата:
и запись у вас скорее всего 1, ведь у вас таблицы связаны, поэтому в Тдатасет должны содержатся только связанные записи.
Даже если я все данные заносил через Microsoft Access? Если я открываю БД через MS Access, то вижу в таблице CODE_PHOTO 3 записи, которые я описал выше.

P.S. Забыл сказать, в Access я тоже создавал связи.
Изображения
Тип файла: jpg 1.jpg (45.3 Кб, 130 просмотров)
Тип файла: png 2.png (17.8 Кб, 103 просмотров)
Если помог, проси поставить минус. Будь оригинален!

Последний раз редактировалось Rin; 14.03.2012 в 14:48.
Rin вне форума Ответить с цитированием
Старый 14.03.2012, 15:29   #4
vovk
!=
Участник клуба
 
Аватар для vovk
 
Регистрация: 08.09.2008
Сообщений: 1,751
По умолчанию

Извините, конечно же это опечатка, и должно быть так
Код:
SQL_ZAPROS.SQL.Text:='INSERT INTO CODE_PHOTO (CODE,PHOTO) VALUES (:code_,:img)';
    SQL_ZAPROS.Parameters.ParamByName('code_').Value:=strtoint(edit1.text);
    SQL_ZAPROS.Parameters.ParamByName('img').LoadFromStream(MemStream,ftBlob);
но я не пойму зачем поле CODE в таблице CODE_PHOTO автоинкримент?

Если так и должно быть, то в запросе его вообще указывать не надо, и запрос будет выглядеть так
Код:
SQL_ZAPROS.SQL.Text:='INSERT INTO CODE_PHOTO (PHOTO) VALUES (:img)';
    SQL_ZAPROS.Parameters.ParamByName('img').LoadFromStream(MemStream,ftBlob);
но не понятно как записи в таблицах будут связаны...

Мне представляется что должно быть как то так:

Если у человека может быть несколько фотографий, то в таблице CODE_PHOTO создайте отдельно первичный ключ,
а поле CODE используйте как внешний ключ ссылку на поле CODE в таблице CODE_FIO_WORKER

Если фото только 1, то сделайте поле CODE в таблице числовым первичным ключом
(не автоинкрементное, которое счётчик а просто числовое целое или какой там тип используется в в акцесс для автоинкрементных полей? длинное целое?),
и опять же используйте как внешний ключ ссылку на поле

И в том и в другом случае пользуемся запросом

Код:
SQL_ZAPROS.SQL.Text:='INSERT INTO CODE_PHOTO (CODE,PHOTO) VALUES (:code_,:img)';
    SQL_ZAPROS.Parameters.ParamByName('code_').Value:=;//тут подставляем значение поля CODE соответствующей записи в таблице CODE_FIO_WORKER
    SQL_ZAPROS.Parameters.ParamByName('img').LoadFromStream(MemStream,ftBlob);

Последний раз редактировалось vovk; 14.03.2012 в 15:52.
vovk вне форума Ответить с цитированием
Старый 15.03.2012, 13:51   #5
Rin
Негодник
Форумчанин
 
Аватар для Rin
 
Регистрация: 10.11.2009
Сообщений: 880
По умолчанию

Спасибо огромное, vovk.
На счёт "code is not valid integer value" - мой косяк. Прошу прощения , что ввёл вас в заблуждение. У меня поле ввода на другой форме лежало, и скопировав ваш код, забыл приписать принадлежность определённой форме.
Репутацию уже добавлял и не могу пока что добавить ещё. Но обещаю, как только добавлю ещё-кому-то, сразу же добавлю вам
После того, как дописал принадлежность форме, все заработало. С помощью SQL-запроса разрешено добавлять значение даже в счётчик (AutoInc).

Кстати, если в T_CODE_PHOTO:TADOTable убрать связи ( то есть MasterSource и MasterField), то код
Код:
showmessage(inttostr(DataModule3.T_CODE_PHOTO.RecordCount));
выдаст значение 10. А если связи оставить, то значением будет 1. Интересное кино).
Благодарю ещё раз.
Если помог, проси поставить минус. Будь оригинален!

Последний раз редактировалось Rin; 15.03.2012 в 14:01.
Rin вне форума Ответить с цитированием
Старый 15.03.2012, 14:07   #6
vovk
!=
Участник клуба
 
Аватар для vovk
 
Регистрация: 08.09.2008
Сообщений: 1,751
По умолчанию

Цитата:
Кстати, если в T_CODE_PHOTO:TADOTable убрать связи ( то есть MasterSource и MasterField), то код
Код:

showmessage(inttostr(DataModule3.T_ CODE_PHOTO.RecordCount));

выдаст значение 10. А если связи оставить, то значением будет 1. Интересное кино)
Ничего удивительного, остаются только связанные "записи".
Цитата:
С помощью SQL-запроса разрешено добавлять значение даже в счётчик (AutoInc).
Я и не говорил что нельзя, просто поле счётчик тут не имеет смысла, и рано или поздно появятся несвязанные записи.
vovk вне форума Ответить с цитированием
Старый 15.03.2012, 17:43   #7
Rin
Негодник
Форумчанин
 
Аватар для Rin
 
Регистрация: 10.11.2009
Сообщений: 880
По умолчанию

Просто это для меня было ново, вот и решил поделиться открытиями))).
Если помог, проси поставить минус. Будь оригинален!
Rin вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
(С++) как добавить в файл запись PotatoCaptain Помощь студентам 6 06.06.2014 23:12
Dataset - как создать новую пустую запись? delphicoding Общие вопросы Delphi 4 11.09.2011 13:59
Как добавить новую страницу на движке Kinokpk releaser shevron PHP 2 04.09.2011 22:17
как удалить строку из combobox, если такая уже есть и добавить в начало новую? codermoder Общие вопросы Delphi 6 14.01.2011 17:33