Как и обещал и не долго думая написал пару запросов к БД 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
1 При удалении записей они все-таки остаются в таблице, так как размер файла базы не уменьшается, записи как то можно увидеть с пометкой «удалено»?
2 фактически при добавлении записей , данные в файл добавлены не будут, пока не закроется само приложение. Где хранятся тогда данные? Это вроде называется принудительным сбросом кеша на диск?)
почему же? все добавляется и удаляется, у Вас какая версия Delphi и Access?
Вот есть вопрос такого характера вот если добавляем через запрос новую запись
//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
У Вас запрос не правильный, должно быть, что-то вроде:
ADOQuery1.SQL.Add(‘INSERT INTO Òîâàð(Name,Income,Price) VALUES (‘+edit1.text’+,’+IntToStr(Edit2.text)+’,’+IntToStr(Edit3.Text)+’)’);
Спасиб буду дома проверю. А вот насчет счетчика базы даных че делать то?
может у тебя уже какие-то записи удалялись, а индексное поле не ведет счет сначала
{[Error] Unit2.pas(54): There is no overloaded version of ‘IntToStr’ that can be called with these arguments}
Вот че он мне написал на этот листинг.
на какой именно? было бы неплохо, чтобы Вы скинули ваш проект
Скинуть не проблема. Куда скидывать?
на любой файлообменник, а сюда ссылку
http://files.mail.ru/CA2EB72EA.....810CDD0DA2
Там на второй форме.
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 в таблицы Товар, Вы использете зарезервированное имя.
Спасибо заработало. Переименовал в таблице поле. и в запросах поправил только вот теперь когда добавляю запись все добовляетса но поле нам при это остаетса пустым.
Все разобралса спасиб большое
всегда пожалуйста!
А как можно с вами связатса? необходима консультация по зазработке собственного класса В томже делфи. Прочел в двух книгах но результат отрицательный.
только по скайпу — andrey_z53
Вот еще вопрос. как правельно и где написать
(id:=ADOQuery1.Fields.Fields[0].AsInteger;) так как в events выдает ошибку.
пробовал так:
DBGrid1.OnCellClick(Id:=ADOQuery1.Fields.Fields[0].AsInteger);
Тож ошибку выдет.
id:=ADOQuery1.Fields.Fields[0].AsInteger
Это напишите на событие OnClick компоненте TDbGrid
Дык вот в это и упераюсь. два раза клацаю на DBGrid1 он не генерирует код а открывает редактор полей.
Пробовал писать так:
Procedure Tform2.dbgrid1.oncellclick(sender: Tobject);
Begin
id:=ADOQuery1.Fields.Fields[0].AsInteger;
end;
Но это тож ему не понравилось.
Потому что TDbgGrid необходимо выставить свойство Options-dgEditing в False и данный код заменить на:
id:=ADOQuery1.Fields.Fields[0].AsInteger;
ShowMessage(IntToStr(id));
И это событие у Вас одинарного клика, а не двойного, поэтому два раза жать бесполезно, оно возникнет на первый щелчок
Я так и не понял в какой части кода надо печатать: id:=ADOQuery1.Fields.Fields[0].AsInteger;
там где и было
А в листинге можно? Для особо тупых. ПЛЗ.
Procedure Tform2.dbgrid1.oncellclick(sender: Tobject);
Begin
id:=ADOQuery1.Fields.Fields[0].AsInteger;
ShowMessage(IntToStr(id));
end;
и в TDbgGrid необходимо выставить свойство Options-dgEditing в False
Выдает вот такую ошибку…
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
а код какой написали?
Который вы дали. Ссыль но программу дал.
Потому что у Вас событие не то, посмотрите внимательно!
procedure TForm2.DBGrid1CellClick(Column: TColumn);
begin
id:=ADOQuery1.Fields.Fields[0].AsInteger;
ShowMessage(IntToStr(id));
end;
Поменял теперь пишет вот такое:
[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’
у Вас событие нет такого понимаете? Вы обработчик создайте, перейдите в список событие и найдете его, затем нажмите двойным щелчком и напишите тот код, что дал Вам!
Еврика заработало только теперь при нажатие клавиши дает ошибку:
Project Project.exe raised exception class EDatabaseError with message ‘DOQuery1: Parameter ‘pid’ not found’. Ну и отстановка процесса.
В свойства.параметры добавил один с именем pid и типом переменной Integer.
http://files.mail.ru/9162EE33D.....5251F30376
а можно вопрос, в последнем типе запроса,на обновление,ниже строчка у вас
ADOQuery1.Parameters.ParamByName(‘pid’).Value:=id;
что она делает? непонятно
здесь мы добавляем параметр, по которому в условии будем отбирать записи
Эх, поздновато я эти статьи начал читать… А то бы применил 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:= ‘Омск…';
Есть сомнения в работоспособности такого кода (например, с какой записи пойдет дальнейший отсчет), но пока ничего лучше не придумал, увы. :-((
там где Вы делаете проверку, то сразу вставляейте новую запись, с новым адресом
Да вот сомневаюсь, каким методом воспользоваться: Insert, InsertRecord, Append или AppendRecord. Может быть есть процедура, которая сразу копирует всю текущую строку? А то копировать каждое поле как-то не очень хочется. В примере-то все просто выглядит, а в реальной задаче в базе данных полей намного больше (в моей 10 полей). Если все «забивать» в строку:
ADOTable1.AppendRecord([var1,var2,…,varN]);
то как разобраться, в правильные поля скопируются данные, или нет. Если порядок полей базе поменяется? Будет не Фамилия-Имя-Адрес, а Адрес-Имя-Фамилия. Можно ли в AppendRecord присваивать значения не по порядковому номеру поля, а по значению, типа
ADOTable1.fieldbyname(‘Name’).AsString:= varName;?
Вообще лучше бы AdoQuery, но само просто Insert
Здравствуйте,
вопрос такой,почему размер фаила базы не изменяется при удалении записей?
Возможно после отсоидинения от базы она уменьшается
А не будет ли ошибки при удалении строки на которую указывает 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;
для удаления строки можно использовать просто AdoQuery.Delete и Вам будет удалять только ту запись на которой стоит указатель
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;
Здравствуйте!
У студента ,вот какой вопрос: а можно сделать чтобы в следующей строке: ADOQuery1.SQL.Add(‘INSERT INTO Student(fio,oz) VALUES(»Иванов Иван Иванович»,10)’); кнопки добавить ,попадали значения из edit1 и edit2 ??? а не по умолчанию Иванов И И. И если можно пример кода.
Конечно можно, надо просто вместо значений по умолчанию написать ‘+Edit.Text+’,’+Edit2.Text+’
Здраствуйте, статья классная, все очень понятно, за что большое спасибо!!!Единственное что не работает-это удаление((((( У меня создана база в MySQL, где несколько талиц.Добавление, редактирование работает, не работает удаление ни через запрос, ни через функцию((((Ошибка: Аргументы имеют неверный тип, выходят за пределы допустимого диапазона или вступают в конфликт друг с другом!!!!
можно конкретно Ваш код удаления? у Вас таблицы связанные?
да, у меня таблицы связанные: таблица-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;
у Вас таблицы каким образом связаны? может Вы не правильно указали тип параметра?
вот 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;
Спасибо большое, просто искал как произвести удаление строки ежели используешь для отображения таблицы ADOQuery, почти оргазм испытал, когда решение увидел.Молодец бл, а то бы изда бы мне была бы.
да незачто, всегда пожалуйста
подскажите, пожалуйста, как прописать:
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;
что именно прописать? у Вас тут ошибка?
я точно не знаю, как прописать через edit поля таблицы, т.е. напишите, пожалуйста, что бужет в Valyes(») через edit поля моей таблицы Student(SHIFR(тип char),NAIMEN(тип char), iIZDATEL(тип char), GOD(тип datetime),KOLICH(тип integer), STOIMOST(тип integer), AFTOR(тип varchar), SPISANO(тип char)
А чего Вы редактируете запросом? Редактируйте так AdoQuery1.Edit; и затем присваивайте каждому полю новое значение
если редактировать так, то данные редактируются в таблице на одной форме, но если перейти на другую форму, где эта же таблица, то там данные не изменились, они, конечно же, изменятся, если перезапустить проект(((а это не правильно
потому что в конце надо ставить AdoQuery.Post после редактирования
я ставлю, но ничего не работает(((((
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;
а Вы попробуйте так AdoQuery.Fields.Field[0].AsString:=Edit1.Text
и так далее
так тоже не работает, может стоит на каждой форме заново подключаться к БД, я точно не знаю как это сделать, но думаю череp ADOConnection
Ну Вы же делаете запросы, если бы не было подключения, то была бы ошибка
Подскажите пожалуйста, а как в поле 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′);
причем перепробовал много вариантов форматов времени, и ни чего не помогло, даже гугл пока мне не помог.
а Вы попробуйте использовать TimeToStr или StrToTime
Вопрос решен, дело оказалось не в формате времени, а в самом поле time, как мне посоветовали на одном форуме, переименовать поле, так как time зарезервированная переменная в Access
отлично тогда, что решили свою проблему
здравствуйте)нужен ваш совет. бд состоит из 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;
выскакивает ошибка: Аргументы имеют неверный тип, выходят за пределы допустимого диапазона или вступают в конфликт друг с другом!!!!
что с этим можно сделать????
необходимо отследить, какой формат данных Вы записывате в таблицы, можно там действительно выходит за пределы типа данных!
pid и tab_nomer типа integer. как это можно отследить и что значит за пределы типа данных??
ну например, тип iteger включается от -65 тыс до +65 тыс и так далее, вдруг у Вас число какое-то выходит за диапазон!
В этой строке не может быть проблема???
ADOQuery1.Parameters.ParamByName(‘pid’).Value:=tab_nomer;
Ведь Value тип Variant, а tab_nomer Integer?????
оно само определит в таком случае тип. Но Вам бы посоветовал для pid выставить тип тоже Iteger!
Здравствуйте!
Проблема с добавлением параметра для ADOQuery.
Вроде и сделал все, что указано, а все равно при попытке компилляции выдается:
… ‘ADOQueryl: Parameter not found’ …
Проект и вложенные в него файлы со скриншотами прилагаются здесь:
http://files.mail.ru/E2CC6B7C3.....89F488BBA5
Это реализуется форме Poisk, чтобы зайти на нее надо в главной кликнуть на кнопку Button1
на форуме посоветовали сделать некоторые преобразования в коде и ошибка Аргументы имеют неверный тип, выходят за пределы допустимого диапазона или вступают в конфликт друг с другом!!!! исчезла.
вот код
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.
что можете посоветовать???
при компиляции такая ошибка?
вообщем с параметром я разобралась,а вот ошибка Аргументы имеют неверный тип, выходят за пределы допустимого диапазона или вступают в конфликт друг с другом!!!! вернулась на место. при пошаговой проверке ругается именно на строку с запросом.
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 ‘);
помогите решить проблему пожалуйста
у Вас в таблице БД все поля имеют текстовый ТИП данных?
tab_nomer типа integer, остальные поля varchar
Так может лучше сделать поле Текстовый, если Вы в Access работаете!
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;
Добрый день, спасибо большое за статью. Но почему то у меня не удаляются записи.. ошибок нет, просто запись остается на своем месте.. вот кусочек кода:
________________________________________________________
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 он мне верный дает, выводил его в лэйбл для проверки
Чтобы удалить запись, Вам сначала необходимо нажать двойным щелчком, а потом уже удалять. Можно сделать легче — AdoQuery1.Delete и все!
если просто «AdoQuery1.Delete», то
«недостаточные сведения о ключевом столбце для обновления», наверное изза того, что в ADOquery3 выборка с нескольких таблиц
Так вы делаете сперва двойной щелчок? и потом только нажимаете удалить?
пробовал двойной клик, не помогло, и если честно, не понял зачем нужен двойной щелчок.
если вариант с запросом, то есть такое предупреждение:
«variable ‘rec_id’ might not have been initialized»
вообщем такое дело. для проверки я в процедуру 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’ фиксированно, куда бы не ставил указатель.. проверил базу — такого числа — нет
вопрос снялся довольно легко..
добавил на кнопку удаления перед запросом:
«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.
Удаление идет корректно, запись удаляется именно та, которую выбрал.
извиняюсь за множество сообщений.
И большое спасибо за отзывчивость и полезные статьи!
У меня выдает ошибку когда юзаю 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
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 параметр не имеет значения по умолчанию