Как и обещал и не долго думая написал пару запросов к БД MS Access, через которые можно добавлять данные в нашу БД, редактировать, удалять. Да конечно через запросы делать может немного сложнее для кого-то, но не для нас правда? Просто через запросы это все дело происходит быстрее. Например, чтобы удалить все данные нам из таблицы без запросов, то нам необходимо пройти все это дело циклом, а это время, а если записей в БД 200000, а через запрос, если это все дело организовать, то будет на много приятнее, красивее и конечно же быстрее, что немаловажно для нас. Здесь отличия у нас будут следующие:

  • вместо Active мы будем использовать ExecSQL
  • ну и конечно же будем использовать запросы

Кто забыл как мы добавляли, редактировали, удаляли и так далее записи в БД MS Access в Delphi через технологию ADO, сможет посмотреть вот в этой статье.

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

procedure TForm1.FormCreate(Sender: TObject);
begin
try
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('SELECT * FROM Student');
ADOQuery1.Active:=True;
except
on e:Exception do
end;
end;

Здесь ничего нового для Вас нету, мы это уже делали в прошлой статье по Базам данных, так что комментировать тут ничего не буду, мы просто делаем запрос на все записи в таблице нашей — Student.

Далее мы добавим данные с помощью запроса, для этого на событие кнопки OnClick напишем следующий код

procedure TForm1.Button1Click(Sender: TObject);
begin
try
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('INSERT INTO Student(fio,oz) VALUES(''Иванов Иван Иванович'',10)');
ADOQuery1.ExecSQL;
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('SELECT * FROM Student');
ADOQuery1.Active:=True;
except
on e:Exception do
end;
end;

Здесь у нас новый вид запроса INSERT INTO. Здесь мы указываем таблицу, в которую будем добавлять данные, а затем в скобках перечисляются поля, в которые будем вставлять данные, а затем VALUES и в скобках такое же количество данных, сколько указали и полей. Как видите ничего не сложно. И потом ExecSQL мы просто выполняем наш запрос, так как такие запросы надо выполнять, Active здесь не «прокатит«. Запрос делаем мы затем на вывод всех данных, в связи с тем, что после добавление, редактирования, удаления наш DBGrid не хочет обновляться, видно «глючность» ADO поэтому я решил на время решить эту проблему именно так.

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

Далее на событие DBGrid OnCellClick я написал следующее

id:=ADOQuery1.Fields.Fields[0].AsInteger;

id - типа integer, не забудьте объявить.

Здесь мы получаем это самое уникальное поле, а уникальное оно будет всегда потому, что у id в таблице тип Счетчик и он соответственно никогда не будет повторяться.

Так когда мы получили уникальное поле, теперь можно и удалить нам нужную запись

procedure TForm1.Button2Click(Sender: TObject);
begin
try
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('DELETE FROM Student WHERE id=:pid');
ADOQuery1.Parameters.ParamByName('pid').Value:=id;
ADOQuery1.ExecSQL;
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('SELECT * FROM Student');
ADOQuery1.Active:=True;
except
on e:Exception do
end;
end;

Здесь мы запросом DELETE удаляем запись по условию id=:pid. А pid мы присваиваем значение, которое получаем по клику на наш DBGrid. Здесь немного поясню в TAdoQuery есть свойство Parametrs, там нам необходимо добавить параметр новый, указать его имя и тип, в данном случае я выбрал тип — ftInteger. Затем  после запроса мы этот параметр заполняем, а в самом запросе используем, то есть чтобы удалили именно текущую запись, удаляем по условию где задаем с помощью WHERE.

Удалить все данные еще проще

procedure TForm1.Button3Click(Sender: TObject);
begin
try
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('DELETE FROM Student');
ADOQuery1.ExecSQL;
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('SELECT * FROM Student');
ADOQuery1.Active:=True;
except
on e:Exception do
end;
end;

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

И наконец отредактируем данные вот так

procedure TForm1.Button4Click(Sender: TObject);
begin
try
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('UPDATE Student SET fio=''Петров Петр Петрович'',oz=7 WHERE id=:pid');
ADOQuery1.Parameters.ParamByName('pid').Value:=id;
ADOQuery1.ExecSQL;
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('SELECT * FROM Student');
ADOQuery1.Active:=True;
except
on e:Exception do
end;
end;

Здесь используется конструкция UPDATE SET, указываем таблицу где обновлять данные через SET указываем поля, которые обновляем и сразу через «=» задаем им новые значения, ничего сложного, ну и конечно нам надо отредактировать именно выделенную запись (текущую), поэтому также задаем условие WHERE id=:pid. id мы один раз на OnCellClick получаем, поэтому он у нас в любом случае будет чему-то равняться. Ну что как видите ничего сложного. Дальше мы рассмотрим как работать в ADO с BLOB-полями, их преимущества и многое другое.

Кстати, хочу заметить, что если у Вы надумали создать свое предприятие, а точнее общество с ограниченной ответственностью (ООО), то Вам необходимо будет обязательно иметь устав. Вы можете взять за основу образец устава ООО planbusiness.ru, без него Вы просто-напросто не сможете зарегистрировать ООО.

Исходники статьи качаем тут

Автор статьи - Andrey53

Метки: , , , , , ,




К записи “Работа с ADO в Delphi. Часть 3” оставлено комментариев: 90.

  1. яка:

    1 При удалении записей они все-таки остаются в таблице, так как размер файла базы не уменьшается, записи как то можно увидеть с пометкой «удалено»?
    2 фактически при добавлении записей , данные в файл добавлены не будут, пока не закроется само приложение. Где хранятся тогда данные? Это вроде называется принудительным сбросом кеша на диск?)

    • Andrey53:

      почему же? все добавляется и удаляется, у Вас какая версия Delphi и Access?

      • Sanko:

        Вот есть вопрос такого характера вот если добавляем через запрос новую запись
        //procedure TForm1.Button1Click(Sender: TObject);
        //begin
        //try
        //ADOQuery1.SQL.Clear;
        //ADOQuery1.SQL.Add(‘INSERT INTO Student(fio,oz) VALUES(»Иванов Иван Иванович»,10)’);
        //ADOQuery1.ExecSQL;
        //ADOQuery1.SQL.Clear;
        //ADOQuery1.SQL.Add(‘SELECT * FROM Student’);
        //ADOQuery1.Active:=True;
        //except
        //on e:Exception do
        //end;
        //end;
        То он добавляет строго «Иванов Иван Иванович» а как добовлять с класса Tedit Вот мой пример кода выдает ошибку

        procedure TForm2.Button1Click(Sender: TObject);
        begin
        try
        ADOQuery1.SQL.Clear;
        ADOQuery1.SQL.Add(‘INSERT INTO Òîâàð(Name,Income,Price) VALUES (edit1.text,IntToStr(Edit2.text),IntToStr(Edit3.Text))’);
        ADOQuery1.ExecSQL;
        ADOQuery1.SQL.Clear;
        ADOQuery1.SQL.Add(‘SELECT ¹,Name,Income,Price From Òîâàð’);
        ADOQuery1.Active:=True;
        except
        on e:Exception do
        end;
        end;

        И да даже если добовлять через програамму записи строго указаные то почему то индексное поле в базе не последовательно а может после 2 записи считать сразу 5

        • Andrey:

          У Вас запрос не правильный, должно быть, что-то вроде:
          ADOQuery1.SQL.Add(‘INSERT INTO Òîâàð(Name,Income,Price) VALUES (‘+edit1.text’+,’+IntToStr(Edit2.text)+’,’+IntToStr(Edit3.Text)+’)’);

          • Sanko:

            Спасиб буду дома проверю. А вот насчет счетчика базы даных че делать то?

          • Andrey:

            может у тебя уже какие-то записи удалялись, а индексное поле не ведет счет сначала

          • Sanko:

            {[Error] Unit2.pas(54): There is no overloaded version of ‘IntToStr’ that can be called with these arguments}

            Вот че он мне написал на этот листинг.

          • Andrey:

            на какой именно? было бы неплохо, чтобы Вы скинули ваш проект

          • Sanko:

            Скинуть не проблема. Куда скидывать?

          • Andrey:

            на любой файлообменник, а сюда ссылку

          • Sanko:

            http://files.mail.ru/CA2EB72EA.....810CDD0DA2

            Там на второй форме.

          • Andrey:

            procedure TForm2.Button1Click(Sender: TObject);
            begin
            try
            ADOQuery1.SQL.Clear;
            ADOQuery1.SQL.Add(‘INSERT INTO Товар(Nam,income,price) VALUES (»’+edit1.text+»’,’+Edit2.text+’,’+Edit3.Text+’)’);
            ADOQuery1.ExecSQL;
            ADOQuery1.SQL.Clear;
            ADOQuery1.SQL.Add(‘SELECT №,Nam,Income,Price From Товар’);
            ADOQuery1.Active:=True;
            except
            on e:Exception do
            end;
            end;

            Вот Ваш код, и в базе необходимо поменять поле Name на Nam в таблицы Товар, Вы использете зарезервированное имя.

          • Sanko:

            Спасибо заработало. Переименовал в таблице поле. и в запросах поправил только вот теперь когда добавляю запись все добовляетса но поле нам при это остаетса пустым.

          • Sanko:

            Все разобралса спасиб большое

          • Andrey:

            всегда пожалуйста!

          • Sanko:

            А как можно с вами связатса? необходима консультация по зазработке собственного класса В томже делфи. Прочел в двух книгах но результат отрицательный.

          • Andrey:

            только по скайпу — andrey_z53

          • Sanko:

            Вот еще вопрос. как правельно и где написать
            (id:=ADOQuery1.Fields.Fields[0].AsInteger;) так как в events выдает ошибку.
            пробовал так:
            DBGrid1.OnCellClick(Id:=ADOQuery1.Fields.Fields[0].AsInteger);
            Тож ошибку выдет.

          • Andrey:

            id:=ADOQuery1.Fields.Fields[0].AsInteger
            Это напишите на событие OnClick компоненте TDbGrid

          • Sanko:

            Дык вот в это и упераюсь. два раза клацаю на DBGrid1 он не генерирует код а открывает редактор полей.
            Пробовал писать так:
            Procedure Tform2.dbgrid1.oncellclick(sender: Tobject);
            Begin
            id:=ADOQuery1.Fields.Fields[0].AsInteger;
            end;

            Но это тож ему не понравилось.

          • Andrey:

            Потому что TDbgGrid необходимо выставить свойство Options-dgEditing в False и данный код заменить на:
            id:=ADOQuery1.Fields.Fields[0].AsInteger;
            ShowMessage(IntToStr(id));
            И это событие у Вас одинарного клика, а не двойного, поэтому два раза жать бесполезно, оно возникнет на первый щелчок

          • Sanko:

            Я так и не понял в какой части кода надо печатать: id:=ADOQuery1.Fields.Fields[0].AsInteger;

          • Andrey:

            там где и было

          • Sanko:

            А в листинге можно? Для особо тупых. ПЛЗ.

          • Andrey:

            Procedure Tform2.dbgrid1.oncellclick(sender: Tobject);
            Begin
            id:=ADOQuery1.Fields.Fields[0].AsInteger;
            ShowMessage(IntToStr(id));
            end;
            и в TDbgGrid необходимо выставить свойство Options-dgEditing в False

          • Sanko:

            Выдает вот такую ошибку…

            Build
            [Error] Unit2.pas(84): Declaration of ‘dbgrid1′ differs from previous declaration
            [Error] Unit2.pas(86): Undeclared identifier: ‘ADOQuery1′
            [Error] Unit2.pas(86): Missing operator or semicolon
            [Fatal Error] Project1.dpr(6): Could not compile used unit ‘Unit2.pas’
            Это на всяк случай
            http://files.mail.ru/FF689B295.....146CF85D38

          • Andrey:

            а код какой написали?

          • Sanko:

            Который вы дали. Ссыль но программу дал.

          • Andrey:

            Потому что у Вас событие не то, посмотрите внимательно!

            procedure TForm2.DBGrid1CellClick(Column: TColumn);
            begin
            id:=ADOQuery1.Fields.Fields[0].AsInteger;
            ShowMessage(IntToStr(id));
            end;

          • Sanko:

            Поменял теперь пишет вот такое:
            [Error] Unit2.pas(84): Undeclared identifier: ‘DBGrid1CellClick’
            [Error] Unit2.pas(84): ‘;’ expected but ‘(‘ found
            [Error] Unit2.pas(86): Undeclared identifier: ‘ADOQuery1′
            [Error] Unit2.pas(86): Missing operator or semicolon
            [Fatal Error] Project1.dpr(6): Could not compile used unit ‘Unit2.pas’

          • Andrey:

            у Вас событие нет такого понимаете? Вы обработчик создайте, перейдите в список событие и найдете его, затем нажмите двойным щелчком и напишите тот код, что дал Вам!

          • Sanko:

            Еврика заработало только теперь при нажатие клавиши дает ошибку:
            Project Project.exe raised exception class EDatabaseError with message ‘DOQuery1: Parameter ‘pid’ not found’. Ну и отстановка процесса.
            В свойства.параметры добавил один с именем pid и типом переменной Integer.
            http://files.mail.ru/9162EE33D.....5251F30376

  2. Alex:

    а можно вопрос, в последнем типе запроса,на обновление,ниже строчка у вас
    ADOQuery1.Parameters.ParamByName(‘pid’).Value:=id;
    что она делает? непонятно

  3. woodhead:

    Эх, поздновато я эти статьи начал читать… А то бы применил TADOQuery вместо TADOTable.

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

    «ADOQuery1.SQL.Add(‘INSERT INTO Student(fio,oz) VALUES(»Иванов Иван Иванович»,10)’);»

    Например, в базе данных есть поля ‘Фамилия’, ‘Имя’, ‘Адрес’. Проживающие (несколько человек) по одному из адресов переехали в другой город, и мне нужно оставить существующие записи с адресом, а также добавить новые записи с новым адресом (тогда в базе будет список всех адресов, по которым проживали эти люди).

    Вот схема кода с выделенным непонятным местом. Надеюсь на вашу помощь.

    procedure TForm1.FormCreate(Sender: TObject);
    begin
    ADOTable1.Active:=False;
    ADOTable1.TableName:=’AddressBook';
    ADOTable1.Active:=True;
    ADOTable1.First;
    While not ADOTable1.eof do
    begin
    if (ADOTable1.fieldbyname(‘Address’).AsString = ‘Москва…’) then
    begin
    ADOTable1.Edit;
    …………………// вот здесь непонятно, что делать
    ADOTable1.Post;
    end;
    ADOTable1.Next;//переходим на следующую запись
    end;
    end;

    У меня только один вариант, довольно громоздкий: скопировать неизменяемые данные полей записи в промежуточные переменные (varSurname, varName), затем выполнить

    ADOTable1.AppendRecord([varSurname,varName,’Омск’]);

    или даже так:

    ADOTable1.Insert;
    ADOTable1.fieldbyname(‘Surname’).AsString:= varSurname;
    ADOTable1.fieldbyname(‘Name’).AsString:= varName;
    ADOTable1.fieldbyname(‘Address’).AsString:= ‘Омск…';

    Есть сомнения в работоспособности такого кода (например, с какой записи пойдет дальнейший отсчет), но пока ничего лучше не придумал, увы. :-((

    • Andrey53:

      там где Вы делаете проверку, то сразу вставляейте новую запись, с новым адресом

      • woodhead:

        Да вот сомневаюсь, каким методом воспользоваться: Insert, InsertRecord, Append или AppendRecord. Может быть есть процедура, которая сразу копирует всю текущую строку? А то копировать каждое поле как-то не очень хочется. В примере-то все просто выглядит, а в реальной задаче в базе данных полей намного больше (в моей 10 полей). Если все «забивать» в строку:

        ADOTable1.AppendRecord([var1,var2,…,varN]);

        то как разобраться, в правильные поля скопируются данные, или нет. Если порядок полей базе поменяется? Будет не Фамилия-Имя-Адрес, а Адрес-Имя-Фамилия. Можно ли в AppendRecord присваивать значения не по порядковому номеру поля, а по значению, типа

        ADOTable1.fieldbyname(‘Name’).AsString:= varName;?

  4. Игорь:

    Здравствуйте,
    вопрос такой,почему размер фаила базы не изменяется при удалении записей?

  5. Павел:

    А не будет ли ошибки при удалении строки на которую указывает id?
    Ведь id меняется когда я кликаю на ячейке:
    id:=ADOQuery1.Fields.Fields[0].AsInteger;
    Но ведь я могу менять положение курсора с помощью клавиш на клавиатуре. Мне кажется что логичнее было бы узнать номер текущей записи у самой ADOQuery1.
    Вот так:

    procedure TForm1.btn1Click(Sender: TObject);
    var
    IndexRecord:integer;
    begin
    try
    IndexRecord:=ADOQuery1.FieldByName(‘id’).AsInteger;
    ADOQuery1.SQL.Clear;
    ADOQuery1.SQL.Add(‘DELETE FROM Patient WHERE id=:pid’);
    ADOQuery1.Parameters.ParamByName(‘pid’).Value:=IndexRecord;
    ADOQuery1.ExecSQL;
    ADOQuery1.SQL.Clear;
    ADOQuery1.SQL.Add(‘SELECT * FROM Patient’);
    ADOQuery1.Active:=True;
    except
    on e:Exception do
    end;
    end;

    • Andrey:

      для удаления строки можно использовать просто AdoQuery.Delete и Вам будет удалять только ту запись на которой стоит указатель

  6. Павел:


    procedure TForm1.btn1Click(Sender: TObject);
    var
    IndexRecord:integer;
    begin
    try
    IndexRecord:=ADOQuery1.FieldByName(‘id’).AsInteger;
    ADOQuery1.SQL.Clear;
    ADOQuery1.SQL.Add(‘DELETE FROM Patient WHERE id=:pid’);
    ADOQuery1.Parameters.ParamByName(‘pid’).Value:=IndexRecord;
    ADOQuery1.ExecSQL;
    ADOQuery1.SQL.Clear;
    ADOQuery1.SQL.Add(‘SELECT * FROM Patient’);
    ADOQuery1.Active:=True;
    except
    on e:Exception do
    end;
    end;

  7. Евгений:

    Здравствуйте!
    У студента ,вот какой вопрос: а можно сделать чтобы в следующей строке: ADOQuery1.SQL.Add(‘INSERT INTO Student(fio,oz) VALUES(»Иванов Иван Иванович»,10)’); кнопки добавить ,попадали значения из edit1 и edit2 ??? а не по умолчанию Иванов И И. И если можно пример кода.

    • Andrey:

      Конечно можно, надо просто вместо значений по умолчанию написать ‘+Edit.Text+’,’+Edit2.Text+’

  8. Studentka:

    Здраствуйте, статья классная, все очень понятно, за что большое спасибо!!!Единственное что не работает-это удаление((((( У меня создана база в MySQL, где несколько талиц.Добавление, редактирование работает, не работает удаление ни через запрос, ни через функцию((((Ошибка: Аргументы имеют неверный тип, выходят за пределы допустимого диапазона или вступают в конфликт друг с другом!!!!

    • Andrey:

      можно конкретно Ваш код удаления? у Вас таблицы связанные?

      • Studentka:

        да, у меня таблицы связанные: таблица-knigi(nomerknigi-первичный ключ) связана с таблицей-cknigi с полем nomerknigi.
        begin
        if Application.MessageBox(‘Óäàëèòü?’,’Delete’,MB_YESNO)=IDYES then
        begin
        ADOQuery1.SQL.Clear;
        ADOQuery1.SQL.Add(‘Delete From knigi where nomerknigi=:nm’);
        ADOQuery1.Parameters.ParamByName(‘nm’).Value:=nomerknigi;
        ADOQuery1.ExecSQL;
        ADOQuery1.SQL.Clear;
        ADOQuery1.SQL.Add(‘select * from knigi’);
        ADOQuery1.Active:=True;
        end;

        • Andrey:

          у Вас таблицы каким образом связаны? может Вы не правильно указали тип параметра?

  9. Studentka:

    вот SQL коды этих двух таблиц:
    CREATE TABLE `knigi` (
    `nomerknigi` int(11) NOT NULL,
    `janr` char(60) NOT NULL,
    `shifrknigi` varchar(20) NOT NULL,
    `naimenovanie` varchar(70) NOT NULL,
    `izdatelstvo` varchar(70) NOT NULL,
    `godizdanya` varchar(5) DEFAULT NULL,
    `kolichestvostranic` int(11) NOT NULL,
    `stoimost` int(11) NOT NULL,
    `tipknigi` char(60) NOT NULL,
    `aftor` varchar(60) DEFAULT NULL,
    `spisano` varchar(5) DEFAULT NULL,
    `annotaciy` varchar(200) DEFAULT NULL,
    PRIMARY KEY (`nomerknigi`)
    ) ENGINE=InnoDB DEFAULT CHARSET=cp1251;

    CREATE TABLE `ckniga` (
    `nomervidachi` int(11) NOT NULL,
    `nomerknigi` int(11) NOT NULL,
    `datavidachi` date NOT NULL,
    `datasdachi` date NOT NULL,
    `kemvidana` char(60) NOT NULL,
    `kodchitatelay` int(11) DEFAULT NULL,
    PRIMARY KEY (`nomervidachi`),
    KEY `kodchitatelay` (`kodchitatelay`),
    KEY `ckniga_fk2` (`nomerknigi`),
    CONSTRAINT `ckniga_fk1` FOREIGN KEY (`kodchitatelay`) REFERENCES `chitatel` (`kodchitatelay`),
    CONSTRAINT `ckniga_fk2` FOREIGN KEY (`nomerknigi`) REFERENCES `knigi` (`nomerknigi`)
    ) ENGINE=InnoDB DEFAULT CHARSET=cp1251;

  10. Timon:

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

  11. Studentka:

    подскажите, пожалуйста, как прописать:
    procedure TForm1.Button1Click(Sender: TObject);
    begin
    try
    ADOQuery1.SQL.Clear;
    ADOQuery1.SQL.Add(‘INSERT INTO Student(SHIFR(тип char),NAIMEN(тип char), iIZDATEL(тип char), GOD(тип datetime),KOLICH(тип integer), STOIMOST(тип integer), AFTOR(тип varchar), SPISANO(тип char), ANNOT(тип char), HJ(тип chat)) VALUES(»Иванов Иван Иванович»,10)’);
    ADOQuery1.ExecSQL;
    ADOQuery1.SQL.Clear;
    ADOQuery1.SQL.Add(‘SELECT * FROM Student’);
    ADOQuery1.Active:=True;
    except
    on e:Exception do
    end;
    end;

  12. Studentka:

    я точно не знаю, как прописать через edit поля таблицы, т.е. напишите, пожалуйста, что бужет в Valyes(») через edit поля моей таблицы Student(SHIFR(тип char),NAIMEN(тип char), iIZDATEL(тип char), GOD(тип datetime),KOLICH(тип integer), STOIMOST(тип integer), AFTOR(тип varchar), SPISANO(тип char)

    • Andrey:

      А чего Вы редактируете запросом? Редактируйте так AdoQuery1.Edit; и затем присваивайте каждому полю новое значение

  13. Studentka:

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

  14. Studentka:

    я ставлю, но ничего не работает(((((
    procedure TForm7.Button1Click(Sender: TObject);
    begin
    Form2.ADOQuery1.edit;
    Form2.ADOQuery1.FieldByName(‘øèôð êíèãè’).AsString:=Edit1.Text;
    Form2.ADOQuery1.FieldByName(‘íàçâàíèå’).AsString:=Edit2.Text;
    Form2.ADOQuery1.FieldByName(‘èçäàòåëüñòâî’).AsString:=Edit3.Text;
    Form2.ADOQuery1.FieldByName(‘ãîä èçäàíèÿ’).AsString:=Edit4.Text;
    Form2.ADOQuery1.FieldByName(‘êîëè÷åñòâî ñòðàíèö’).AsInteger:=StrToInt(edit5.Text);
    Form2.ADOQuery1.FieldByName(‘ñòîèìîñòü’).AsInteger:=StrToInt(edit6.Text);
    Form2.ADOQuery1.FieldByName(‘àâòîð’).AsString:=Edit7.Text;
    Form2.ADOQuery1.FieldByName(‘ñïèñàíî’).AsString:=Edit8.Text;
    Form2.ADOQuery1.FieldByName(‘àííîòàöèÿ’).AsString:=Edit9.Text;
    Form2.ADOQuery1.FieldByName(‘íîìåð æàíðà’).AsInteger:=StrToInt(Combobox1.Text);
    Form2.ADOQuery1.Post;
    edit1.Clear;
    edit2.Clear;
    edit3.Clear;
    edit4.clear;
    edit5.Clear;
    edit6.Clear;
    edit7.clear;
    edit8.clear;
    edit9.Clear;
    close;

    end;

  15. Studentka:

    так тоже не работает, может стоит на каждой форме заново подключаться к БД, я точно не знаю как это сделать, но думаю череp ADOConnection

  16. nixonn:

    Подскажите пожалуйста, а как в поле time вставить время, при помощи SQL запроса? то есть (INSERT …. и т.д.). Поле time — тип (Дата/Время) — краткий формат времени, БД Access. Вот как пытался сделать я:

    ADOQUery1.SQL.Add(‘INSERT INTO tdata(id_cr,id_pos,data,time) VALUES (10,20,01/05/2013,20:00′);

    причем перепробовал много вариантов форматов времени, и ни чего не помогло, даже гугл пока мне не помог.

  17. nixonn:

    Вопрос решен, дело оказалось не в формате времени, а в самом поле time, как мне посоветовали на одном форуме, переименовать поле, так как time зарезервированная переменная в Access

  18. luna:

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

    procedure TForm1.Button1Click(Sender: TObject);
    begin
    try
    ADOQuery1.SQL.Clear;
    ADOQuery1.SQL.Add(‘UPDATE Sotrudnik SET familia=»васильев»,name=»эдуард»,otchestvo=»петрович» WHERE tab_nomer=:pid’);
    ADOQuery1.Parameters.ParamByName(‘pid’).Value:=tab_nomer;
    ADOQuery1.ExecSQL;
    ADOQuery1.SQL.Clear;
    ADOQuery1.SQL.Add(‘SELECT * FROM Sotrudnik’);
    ADOQuery1.Active:=True;
    except
    on e:Exception do
    end;

    end;

    выскакивает ошибка: Аргументы имеют неверный тип, выходят за пределы допустимого диапазона или вступают в конфликт друг с другом!!!!

    что с этим можно сделать????

    • Andrey:

      необходимо отследить, какой формат данных Вы записывате в таблицы, можно там действительно выходит за пределы типа данных!

  19. luna:

    pid и tab_nomer типа integer. как это можно отследить и что значит за пределы типа данных??

    • Andrey:

      ну например, тип iteger включается от -65 тыс до +65 тыс и так далее, вдруг у Вас число какое-то выходит за диапазон!

  20. luna:

    В этой строке не может быть проблема???
    ADOQuery1.Parameters.ParamByName(‘pid’).Value:=tab_nomer;
    Ведь Value тип Variant, а tab_nomer Integer?????

    • Andrey:

      оно само определит в таком случае тип. Но Вам бы посоветовал для pid выставить тип тоже Iteger!

  21. Евгений:

    Здравствуйте!
    Проблема с добавлением параметра для ADOQuery.

    Вроде и сделал все, что указано, а все равно при попытке компилляции выдается:
    … ‘ADOQueryl: Parameter not found’ …

    Проект и вложенные в него файлы со скриншотами прилагаются здесь:
    http://files.mail.ru/E2CC6B7C3.....89F488BBA5

    Это реализуется форме Poisk, чтобы зайти на нее надо в главной кликнуть на кнопку Button1

  22. luna:

    на форуме посоветовали сделать некоторые преобразования в коде и ошибка Аргументы имеют неверный тип, выходят за пределы допустимого диапазона или вступают в конфликт друг с другом!!!! исчезла.
    вот код
    procedure TForm1.Button1Click(Sender: TObject);
    begin
    try
    ADOQuery1.SQL.Clear;
    ADOQuery1.SQL.Add(‘UPDATE [Sotrudnik] SET [familia]=»васильев»,[name]=»эдуард»,[otchestvo]=»петрович» WHERE [tab_nomer]=:pid
    ’);
    ADOQuery1.Parameters.Refresh;
    ADOQuery1.Parameters.ParamByName(‘pid’).Value:=tab_nomer;
    ADOQuery1.ExecSQL;
    ADOQuery1.SQL.Clear;
    ADOQuery1.SQL.Add(‘SELECT * FROM Sotrudnik’);
    ADOQuery1.Active:=True;
    except
    on e:Exception do
    end;
    end;
    но теперь программа выдает ошибку ADOQuery1.Parameter ‘pid’ not found.

    что можете посоветовать???

    • Andrey:

      при компиляции такая ошибка?

      • luna:

        вообщем с параметром я разобралась,а вот ошибка Аргументы имеют неверный тип, выходят за пределы допустимого диапазона или вступают в конфликт друг с другом!!!! вернулась на место. при пошаговой проверке ругается именно на строку с запросом.

        ADOQuery1.SQL.Add(‘UPDATE Sotrudnik SET familia=»’+Edit2.Text+»’,name=»’+edit3.text+»’,otchestvo=»’+edit4.text+»’,data_rogdenia=»’+edit5.text+»’,telefon=»’+
        edit6.text+»’,adres=»’+edit7.text+»’ WHERE tab_nomer=:pid ‘);

        помогите решить проблему пожалуйста

  23. Евгений:

    procedure TForm3_Poisk.btn3_PokazatClick(Sender: TObject);
    if CheckBox__Kuda.Checked = FALSE and
    CheckBox__NomerReysa.Checked = FALSE and
    CheckBox__Chislo.Checked = TRUE and
    CheckBox__VremyaOtpr.Checked = FALSE then //Выбор по дате отправления
    begin
    ADOQuery1.SQL.Clear;

    ADOQuery1.SQL.Add(‘SELECT Kuda, Data, VremyaOtpr, VremyaPrib, Mesta, Stoimost FROM Таблица1 WHERE ((Data = :DataVyleta) AND (Mesta>0))’);
    ADOQuery1.Parameters.ParamByName(‘DataVyleta’).Value := Form3_Poisk.MaskEdit3_Chislo.Text;
    ADOQuery1.Active:=True;

    end
    else
    begin end;
    end;

    В Access поле Data текстовое с маской ввода !99.99.0000;1;_
    Создан параметр DataVyleta, тип ftString
    Менялся тип параметра на ftIneger результат аналогичный:
    … Несоответствие типов данных в выражении условия …
    ===============================================
    В другом запросе по номеру рейса все проходит хорошо:
    if CheckBox__Kuda.Checked = FALSE and
    CheckBox__NomerReysa.Checked = TRUE and
    CheckBox__Chislo.Checked = FALSE and
    CheckBox__VremyaOtpr.Checked = FALSE then // Выбор по номеру рейса
    begin
    ADOQuery1.SQL.Clear;
    ADOQuery1.SQL.Add(‘SELECT NomerReysa, Kuda, Data, VremyaOtpr, VremyaPrib, Mesta, Stoimost FROM Oaaeeoa1 WHERE ((NomerReysa=:NomReysa) AND (Mesta>0))’);
    AdOQuery1.Parameters.ParamByName(‘NomReysa’).Value := Form3_Poisk.Edit_NomReysa.Text;
    ADOQuery1.Active:=True;
    end
    else
    begin end;

  24. Денис:

    Добрый день, спасибо большое за статью. Но почему то у меня не удаляются записи.. ошибок нет, просто запись остается на своем месте.. вот кусочек кода:
    ________________________________________________________
    procedure Tmain.DBGrid1CellClick(Column: TColumn);
    var
    rec_id:integer;
    begin
    rec_id:=dm1.ADOquery3.Fields.Fields[0].AsInteger;
    end;

    procedure Tmain.SpeedButton5Click(Sender: TObject);
    var
    rec_id:integer;
    begin
    try
    dm1.ADOquery3.SQL.Clear;
    dm1.ADOquery3.SQL.Add(‘DELETE * FROM sotr WHERE id_sotr=:pid’);
    dm1.ADOquery3.Parameters.ParamByName(‘pid’).Value:=rec_id;
    dm1.ADOquery3.ExecSQL;
    dm1.ADOquery3.SQL.Clear;
    dm1.ADOquery3.SQL.Add(‘Select * FROM sotr’);
    dm1.ADOQuery3.Active:=true;
    except
    on e:Exception do
    end;
    end;

    • Денис:

      rec_id он мне верный дает, выводил его в лэйбл для проверки

    • Andrey:

      Чтобы удалить запись, Вам сначала необходимо нажать двойным щелчком, а потом уже удалять. Можно сделать легче — AdoQuery1.Delete и все!

  25. Денис:

    если просто «AdoQuery1.Delete», то
    «недостаточные сведения о ключевом столбце для обновления», наверное изза того, что в ADOquery3 выборка с нескольких таблиц

  26. Денис:

    пробовал двойной клик, не помогло, и если честно, не понял зачем нужен двойной щелчок.
    если вариант с запросом, то есть такое предупреждение:
    «variable ‘rec_id’ might not have been initialized»

  27. Денис:

    вообщем такое дело. для проверки я в процедуру dbgridcellclick добавил смену label на свой rec_id
    «label1.Caption:=inttostr(rec_id);»
    и label меняется на ура, кликаю по гриду label меняется верно..

    добавил кнопку на неё сделал тоже смену label2
    «label2.Caption:=inttostr(rec_id);»
    после нажатия кнопки, label2 становится числом ‘4437684’

    т.е. сперва я кликаю по гриду, одинарным, двойным, тройным щелчаками, и потом на эту кнопку, в итоге ^
    label1 — ‘7’; label2 — ‘4437684’

    мои данные не удаляются потому-что условие WHERE не выполняется..

    причем это число ‘4437684’ фиксированно, куда бы не ставил указатель.. проверил базу — такого числа — нет

  28. Денис:

    вопрос снялся довольно легко..
    добавил на кнопку удаления перед запросом:
    «rec_id:=dm1.ADOquery3.Fields.Fields[0].AsInteger;»

    в итоге получилось так:

    procedure Tmain.SpeedButton5Click(Sender: TObject);
    var
    rec_id:integer;
    begin
    rec_id:=dm1.ADOquery3.Fields.Fields[0].AsInteger;
    try
    dm1.ADOquery3.SQL.Clear;
    dm1.ADOquery3.SQL.Add(‘DELETE FROM sotr WHERE id_sotr=pid’);
    dm1.ADOquery3.Parameters.ParamByName(‘pid’).Value:=rec_id;
    dm1.ADOquery3.ExecSQL;
    dm1.ADOquery3.SQL.Clear;
    dm1.ADOquery3.SQL.Add(‘Select * FROM sotr’);
    dm1.ADOQuery3.Active:=true;
    except
    on e:Exception do
    end;

    end;

    без всякого dbgridcellclick.
    Удаление идет корректно, запись удаляется именно та, которую выбрал.

    извиняюсь за множество сообщений.
    И большое спасибо за отзывчивость и полезные статьи!

  29. Rudi:

    У меня выдает ошибку когда юзаю Update
    код:

    try
    F_Main.ADOQuery1.SQL.Clear;
    F_Main.ADOQuery1.SQL.Add(‘UPDATE Putt SET zam=’ + Edt2.Text +’, dokumentu=’ + Edt5.Text +’, vodii=’ + Edt4.Text +’,data=’ + medt1.Text +’, dogovir=’ + Edt1.Text +’, status=»â î÷³êóâàíí³» WHERE id=:pid’);
    F_Main.ADOQuery1.Parameters.ParamByName(‘pid’).Value:=id;
    F_Main.ADOQuery1.ExecSQL;
    F_Main.ADOQuery1.SQL.Clear;
    F_Main.ADOQuery1.SQL.Add(‘SELECT * FROM Student’);
    F_Main.ADOQuery1.Active:=True;
    except
    on e:Exception do
    end;
    end;

    код ошибки:

    —————————
    Debugger Exception Notification
    —————————
    Project Project1.exe raised exception class EOleException with message ‘Не правильно определён обэкт Parameter. Предоставлены несогласованные или не полные сведение’. Process stopped. Use Step or Run to continue.
    —————————
    OK Help
    —————————

    ссылка на проект http://files.mail.ru/0D52A14FA.....9EE4BC70C7

  30. Влад:

    adoquery1.Close;
    adoquery1.SQL.Add(‘INSERT INTO Ofis1 ( no_sotr, PIB)’);
    adoquery1.SQL.Add(‘SELECT no_sotr, PIB’);
    adoquery1.SQL.Add(‘FROM Ofis WHERE Ofis.Ofis1=1;’);
    adoquery1.ExecSQL;
    adoquery2.Close;
    adoquery2.SQL.Add(‘UPDATE (Ofis1 INNER JOIN Sotrudniku ON’);
    adoquery2.SQL.Add(‘Ofis1.No_sotr = Sotrudniku.No_sotr) INNER JOIN Ofis ON ‘);
    adoquery2.SQL.Add(‘Sotrudniku.No_sotr = Ofis.No_sotr SET Ofis1.Obem_kg’);
    adoquery2.SQL.Add(‘Ofis1.Stavka = [Ofis].[Stavka],’);
    adoquery2.SQL.Add(‘Ofis1.data = [Ofis].[Data] ‘);
    adoquery2.SQL.Add(‘WHERE (((Ofis.No_Ofisa)=1));’);
    adoquery2.ExecSQL;
    dm.Ofiss1.Active:=false;
    dm.Ofiss1.Active:=true;
    Выдает такую ошыбку в чем проблема??
    project raised exception class EOleException with message параметр не имеет значения по умолчанию

Оставить комментарий на Влад

Вы можете использовать следующие теги:

*