Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Базы данных и репортинг > Ошибка при добавлении записи


Автор: NiJazz 12.2.2005, 17:15
Делаею выборку:
Код

Query1.SQL.Clear;
Query1.SQL.Add('select * from Table where Id = MyId');
Query1.Open;

Затем, когда вызывается метод Edit или Append, выдается ошибка "Can not modify read only dataset"
Я что-то забыл сделать?

Автор: Kesh 12.2.2005, 18:44
А TUpdateSQL у тебя для TQuery есть?
Добавлено @ 18:44
Может RequestLive стоит в False...

Автор: Sett 13.2.2005, 15:05
Query1.SQL.Edit;
Query1.SQL.Clear;
Query1.SQL.Edit;
Query1.SQL.Add('select * from Table where Id = MyId');
Query1.Open;

Автор: Vit 13.2.2005, 23:43
Цитата(Sett @ 13.2.2005, 06:05)
Query1.SQL.Edit;
Query1.SQL.Clear;
Query1.SQL.Edit;
Query1.SQL.Add('select * from Table where Id = MyId');
Query1.Open;



Что это было? И зачем первые 2 строки?

Автор: Bes 14.2.2005, 08:30
Вообще плохо понимаю смысл этого синтаксиса. :-(
Напиши что ты хочешь сделать, а то ты вроде хочешь изменить данные а пишешь select...?

Автор: NiJazz 14.2.2005, 09:13
А SQL.Edit зачем? Свойство SQL - типа TStrings. Перед тем как добавлять запрос, нужно очистить содержимое.

Автор: Bes 14.2.2005, 10:26
ДЛя того, чтобы очистить .SQL надо вызвать clear а не edit.
Кроме того, можно написать SQL.text:='что-то';
Я вообще не пользуюсь edit, post, open и пр. только active чтобы смотреть и ExecSQL чтобы менять.

Автор: Vit 14.2.2005, 22:29
Код

Query1.Close;
Query1.SQL.Text:='select * from Table where Id = "MyId"';
Query1.Open;
Query1.Append;
Query1.fieldByName('Id').asstring:='чего-то там';
Query1.Post;

Автор: Bes 15.2.2005, 07:16
2Vit: Попутный вопрос:

Query1.Close;
Query1.SQL.Text:='select * from Table where Id = "MyId"';
Query1.Open; // Это равно Query.Active:=true; ?
Query1.Append; // А это команда что, позволяет менять данные при открытом Query?
Query1.fieldByName('Id').asstring:='чего-то там'; // А если ID - несовпадающий счетчик?
Query1.Post; // А изменения видно сразу после этой команды?

P.S. Как-то такой синтаксис мне не очень... :-( Насколько он правилен?

Автор: NiJazz 15.2.2005, 08:57
Цитата
Query1.Open; // Это равно Query.Active:=true; ?

Да.
Цитата
Query1.Append; // А это команда что, позволяет менять данные при открытом Query?

Добавляет пустую запись в конец таблицы.
Цитата
Query1.fieldByName('Id').asstring:='чего-то там'; // А если ID - несовпадающий счетчик?

То есть? Тут идёт обращение к полю таблицы по имени и присваивание значения (запись).
Цитата
Query1.Post; // А изменения видно сразу после этой команды?

Если изменения не кэшируются, то идёт физическая запись всех изменений. То есть видно. smile

Автор: Bes 15.2.2005, 12:06
Цитата
Query1.fieldByName('Id').asstring:='чего-то там'; // А если ID - несовпадающий счетчик?

То есть? Тут идёт обращение к полю таблицы по имени и присваивание значения (запись).

То есть: есть записи где id = 1, 2, 3, 4, 5
вы создаете "пустую" запись и значение id в ней сразу становится равным 6 т.к. id есть скажем int not null identity unique

дак как вы можете ей присвоить скажем 5? - сама база не даст.....

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

Query.active:=false;
Query.sql.text:='insert into mytab (val1) values (:val1)';
Query.execsql;
Query.sql.text:='select * from mytab';
Query.active:=true;

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

Автор: NiJazz 15.2.2005, 12:15
Bes
Цитата
о есть: есть записи где id = 1, 2, 3, 4, 5
вы создаете "пустую" запись и значение id в ней сразу становится равным 6 т.к. id есть скажем int not null identity unique

дак как вы можете ей присвоить скажем 5? - сама база не даст.....

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

Так меньше вероятность возникновения ошибки при добавлении записи, так как синтаксис проще.

Автор: Vit 15.2.2005, 17:16
Цитата(Bes @ 14.2.2005, 22:16)
Query1.Append; // А это команда что, позволяет менять данные при открытом Query?


Эта комманда открывает Dataset на запись. Есть так называемые Live Query, или запросы с двунаправленными курсорами. Реально такой запрос ведёт себя точно так же как таблица, с ним можно делать всё что ты делаешь с Table - Edit, Insert, Append.

Цитата(Bes @ 14.2.2005, 22:16)
Query1.fieldByName('Id').asstring:='чего-то там'; // А если ID - несовпадающий счетчик?


Откуда я знаю ID счётчик там в таблице или вообще левое значение, я привёл для примера, если это счётчик то его конечно присваивать нельзя, но по условию задачи нигде не оговаривалось что это счётчик а телепатии я не обучен.

Цитата(Bes @ 14.2.2005, 22:16)
Query1.Post; // А изменения видно сразу после этой команды?


Да

Цитата(Bes @ 14.2.2005, 22:16)
P.S. Как-то такой синтаксис мне не очень... :-( Насколько он правилен?


Он правилен, но пользоваться им надо с БОЛЬШОЙ осторожностью. Такие запросы очень напрягают сервер. При многопользовательском доступе с серверами баз данных такие запросы могут очень сильно блокировать таблицу. Кроме того лучше не применять в случае если Select возвращает очень большой набор данных. В общем вопрос очень тонкий - 100% рекомендаций никто не даст, в одних случаях применение такого запроса очень удобно (например именно это происходит если соединить грид с результатом запроса и в гриде поменять значение или добавить запись), в других это можетт явится источником проблем - это универсальный ответ по поводу целесообразности любого запроса.

Цитата(NiJazz @ 14.2.2005, 23:57)
Если изменения не кэшируются, то идёт физическая запись всех изменений. То есть видно. 


Даже если кэшируются, если использовать доступ через тот же драйвер - всё видно.


Цитата(Bes @ 15.2.2005, 03:06)
про код - я имел ввиду, что насколько логичнее будет писать:

Query.active:=false;
Query.sql.text:='insert into mytab (val1) values (:val1)';
Query.execsql;
Query.sql.text:='select * from mytab';
Query.active:=true;

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


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

Цитата(NiJazz @ 15.2.2005, 03:15)
Так меньше вероятность возникновения ошибки при добавлении записи, так как синтаксис проще.


Не в ошибках дело...

Автор: Makarofff 18.2.2005, 17:12
а у меня такая трабла
когда в проге повторно вызываю таблицу пишет
Name not uniaue in this context
помогите плиз

Автор: NiJazz 18.2.2005, 17:16
Makarofff
Создавай новую тему.

Автор: Vit 20.2.2005, 08:00
Цитата(Makarofff @ 18.2.2005, 08:12)
Name not uniaue in this context



У тебя 2 записи с одинкаовыми строками и нет первичного ключа - база данных их различить не может... Ключи надо на таблицы ставить обязательно.



Цитата(NiJazz @ 18.2.2005, 08:16)
Makarofff
Создавай новую тему.



Да! Именно так! Хотите спросить новое - создавайте свою тему!

Автор: Bes 21.2.2005, 07:30
2Vit: Сорри, у меня в голове сработало что раз ID - значит счетчик. :-)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)