![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Значение автоинкремнтного поля и ADOQuery [D7, MSAccess]
parovoZZ © (2006-02-21 18:59:00)Народ, я вставляю Insert-ом запись в таблицу с автоинкрементным полем. Так вот как получить это значение "не отходя от кассы"? Тут подсказали @@identity, но это только для MSSQL, а у меня Access.
Nikolay M. (2006-02-24 14:05:00) [1]
> Я предложил лишь один из способов
Решил с [4] померяться?
> Праативныеее
Угу. Николаи - они тово... вредные...
msguns (2006-02-24 13:58:00) [2]>sniknik © (24.02.06 13:18) [16]
>Nikolay M. © (24.02.06 13:19) [17]
Я же с вами не спорю. Я предложил лишь один из способов, пусть и далеко не самый лучший.
Праативныеее
Nikolay M. (2006-02-24 13:19:00) [3]
> msguns © (24.02.06 13:04) [15]
> Программа, фрагмент которой я привел, работает так: если
> кто-то уже начал писать в базу, то она уже только читает
> (функции обновления не работают).
В этом примере нет ничего, что указывало бы на то, что изменения вносит только один пользователь, а код инициализации двух десятков полей в свете сабжа здесь вообще лишний.
Продолжая тему: если уж очень хочется руками генерировать ID как MAX + 1, то для многопользовательской системы нужна блокировка таблицы.
http://www.compdoc.ru/bd/access/schemes_blocking_in_bd/
sniknik (2006-02-24 13:18:00) [4]> как фрагмент работающей программы
работающей правильно только в силу специфических причин (только один добавляет записи. судя по [15]. да еще и редко т.к. ручной ввод)
имхо не стоит такие методы рекомендовать для всеобщего применения... не у всех "специфика" совпадет.
msguns (2006-02-24 13:04:00) [5]>Nikolay M. © (24.02.06 12:44) [14]
>А чем ахсекс так уникален, что при многопользовательской работе MAX (ID) + 1 не даст граблями по лбу?
Программа, фрагмент которой я привел, работает так: если кто-то уже начал писать в базу, то она уже только читает (функции обновления не работают). Дело в том, что программа предназначена для хранения библиотечной картотеке и основной ее функционал - это быстро искать требуемую литературу. Ввод же в БД значителен только при заполнении базы их описей. В нашей организации только одна девушка работает библиотекарем, - параллировать ее просто не с кем.
А вот смотреть (искать) лиературу будут многие.
Программа писана чисто для "местного" использования и не предназначена для продажи или тиражирования.
Пример привел просто как фрагмент работающейпрограммы, выполняющий описанную в сабже работу (вставка новой записи, определение ее ID и поиск ее в обновленном датасете)
>Название таблицы уж очень знакомо... "BackBone" - говорит о чем-нибудь? :)
Нет
Nikolay M. (2006-02-24 12:44:00) [6]
> msguns © (24.02.06 10:33) [13]
А чем ахсекс так уникален, что при многопользовательской работе MAX (ID) + 1 не даст граблями по лбу?
> INTO CTLG
Название таблицы уж очень знакомо... "BackBone" - говорит о чем-нибудь? :)
msguns (2006-02-24 10:33:00) [7]>Johnmen © (23.02.06 19:06) [12]
Жень, речь-то об акцесе идет ;)
Johnmen (2006-02-23 19:06:00) [8]>msguns © (23.02.06 17:25) [11]
Серёга, зачем ты огорчаешь общественность такими высказываниями?
Особенно 'SELECT MAX(ID)+1 AS NEWID FROM CTLG'
:(
msguns (2006-02-23 17:25:00) [9]
function TdmLibr.DBT_PutCTLG(Rec: PDBRec_CTLG): boolean;
// Добавление / Изменение записи в каталоге
var
NewID: Integer;
begin
result := false;
if Rec.ID=-1 then
with TADOQuery.Create(nil) do
try
Connection := cnLibr;
SQL.Text := 'SELECT MAX(ID)+1 AS NEWID FROM CTLG';
Open;
if RecordCount>0 then
NewID := Fields[0].AsInteger
else
NewID := 1;
Close;
finally
Free;
end
else
NewID := Rec.ID;
if NewID=0 then exit;
with TADOCommand.Create(nil) do
try
Connection := cnLibr;
if Rec.ID=-1 then
CommandText := 'INSERT INTO CTLG (ID,BNAME,TID,BCLTNAME,BCLTVOL,THID,PYEAR,PID,PHID'+
',BINVNUM,BINVNUMA,BPRICE,BDATEIN,BDATEOUT,BAVAIL,CID,UID,ONUM,SNUM,BLANG,BADDR' +
',BSTORR,BSTORB,BSTORS,BSTORN,BAUTORS,BANNOT,BMOVINFO) '+
' VALUES (:ID,:BNAME,:TID,:BCLTNAME,:BCLTVOL,:THID,:PYEAR,:PID,:PHID'+
',:BINVNUM,:BINVNUMA,:BPRICE,:BDATEIN,:BDATEOUT,:BAVAIL,:CID,:UID,:ONUM,:SNUM,:B LANG,:BADDR'+
',:BSTORR,:BSTORB,:BSTORS,:BSTORN,:BAUTORS,:BANNOT,:BMOVINFO) '
else
CommandText := 'UPDATE CTLG SET BNAME=:BNAME,TID=:TID,BCLTNAME=:BCLTNAME,BCLTVOL=:BCLTVOL'+
',THID=:THID,PYEAR=:PYEAR,PID=:PID,PHID=:PHID,BINVNUM=:BINVNUM,BINVNUMA=:BINVNUM A'+
',BPRICE=:BPRICE,BDATEIN=:BDATEIN,BDATEOUT=:BDATEOUT,BAVAIL=:BAVAIL'+
',CID=:CID,UID=:UID,ONUM=:ONUM,SNUM=:SNUM,BLANG=:BLANG,BADDR=:BADDR,BSTORR=:BSTO RR '+
',BSTORB=:BSTORB,BSTORS=:BSTORS,BSTORN=:BSTORN,BAUTORS=:BAUTORS'+
',BANNOT=:BANNOT, BMOVINFO=:BMOVINFO'+
' WHERE ID=:ID ';
Parameters.ParamByName('ID').Value := NewID;
Parameters.ParamByName('BNAME').Value := Rec.BNAME;
Parameters.ParamByName('TID').Value := Rec.TID;
Parameters.ParamByName('BCLTNAME').Value := Rec.BCLTNAME;
Parameters.ParamByName('BCLTVOL').Value := Rec.BCLTVOL;
Parameters.ParamByName('THID').Value := NULL;
if Rec.THID>-1 then Parameters.ParamByName('THID').Value := Rec.THID;
Parameters.ParamByName('PYEAR').Value := NULL;
if Rec.PYEAR>0 then Parameters.ParamByName('PYEAR').Value := Rec.PYEAR;
Parameters.ParamByName('PID').Value := NULL;
if Rec.PID>-1 then Parameters.ParamByName('PID').Value := Rec.PID;
Parameters.ParamByName('PHID').Value := NULL;
if Rec.PHID>-1 then Parameters.ParamByName('PHID').Value := Rec.PHID;
Parameters.ParamByName('BINVNUM').Value := Rec.BINVNUM;
Parameters.ParamByName('BINVNUMA').Value := Rec.BINVNUMA;
Parameters.ParamByName('BPRICE').Value := NULL;
if Rec.BPRICE>0 then Parameters.ParamByName('BPRICE').Value := Rec.BPRICE;
Parameters.ParamByName('BDATEIN').Value := NULL;
Parameters.ParamByName('BDATEOUT').Value := NULL;
if Rec.BDATEIN>0 then Parameters.ParamByName('BDATEIN').Value := DateToStr(Rec.BDATEIN);
if Rec.BDATEOUT>0 then Parameters.ParamByName('BDATEOUT').Value := DateToStr(Rec.BDATEOUT);
Parameters.ParamByName('BAVAIL').Value := Rec.BAVAIL;
Parameters.ParamByName('CID').Value := NULL;
if Rec.CID>-1 then Parameters.ParamByName('CID').Value := Rec.CID;
Parameters.ParamByName('UID').Value := NULL;
if Rec.UID>-1 then Parameters.ParamByName('UID').Value := Rec.UID;
Parameters.ParamByName('ONUM').Value := Rec.ONUM;
Parameters.ParamByName('SNUM').Value := Rec.SNUM;
Parameters.ParamByName('BLANG').Value := Rec.BLANG;
Parameters.ParamByName('BADDR').Value := Rec.BADDR;
Parameters.ParamByName('BSTORR').Value := Rec.BSTORR;
Parameters.ParamByName('BSTORB').Value := Rec.BSTORB;
Parameters.ParamByName('BSTORS').Value := Rec.BSTORS;
Parameters.ParamByName('BSTORN').Value := NULL;
if Rec.BSTORN>0 then Parameters.ParamByName('BSTORN').Value := Rec.BSTORN;
Parameters.ParamByName('BAUTORS').Value := Rec.BAUTORS;
Parameters.ParamByName('BANNOT').Value := Rec.BANNOT;
Parameters.ParamByName('BMOVINFO').Value := Rec.BMOVINFO;
Execute;
result := true;
Rec.ID := NewID;
finally
Free;
end;
end;
parovoZZ (2006-02-23 16:21:00) [10]Вообщем, изучив всё выше названное, родилось следующее:
SQL := 'SELECT @@Identity as ID';
ADOQuery.Close;
ADOQuery.SQL.Clear;
ADOQuery.SQL.Add(SQL);
ADOQuery.Open;
i := ADOquery.FieldByName ('ID').AsInteger;
Вроде "показания" правильные.
Nikolay M. (2006-02-23 14:28:00) [11]
> Тут подсказали @@identity, но это только для MSSQL,
http://www.sql.ru/faq/faq_topic.aspx?fid=214
Q8.
parovoZZ (2006-02-22 20:55:00) [12]Истина где-то рядом?
Как же быть?
Johnmen (2006-02-22 13:29:00) [13]Тем, что
1. SELECT MAX(<автоинкрементное поле>) AS LastID FROM <table name>
истинный результат не гарантирует.
2. Query.ExecSQL;
Query.FieldByName (<автоинкрементное поле>).AsInteger;
нет НД нет и результата.
ALIES (2006-02-22 12:40:00) [14]
> Прошу прощения, но это бред от первой строки до последней.
> ..:)
В чем имнно?
Johnmen (2006-02-22 12:16:00) [15]>ALIES (22.02.06 12:05) [4]
Прошу прощения, но это бред от первой строки до последней...:)
ALIES (2006-02-22 12:05:00) [16]SELECT MAX(<автоинкрементное поле>) AS LastID FROM <table name>
В дельфях
Query.FieldByName ('LastID').AsInteger;
А вообще при добавлении записи курсор устанавливается на новую запись,
поэтому можно сразу из Query взять значение
Query.ExecSQL;
Query.FieldByName (<автоинкрементное поле>).AsInteger;
parovoZZ (2006-02-22 08:54:00) [17]
> Anatoly Podgoretsky © (21.02.06 19:56) [1]
> SELECT @@IDENTITY
А из ADOQuery как его вытащить? FieldByName (@@IDENTITY).Value ?
> ALIES (22.02.06 07:43) [2]
> Подробнее, что значить "не отходя от кассы"? Что имено тебе
> надо вставить?
Не вставить, а получить. Сразу же, после вставки записи.
ALIES (2006-02-22 07:43:00) [18]Подробнее, что значить "не отходя от кассы"? Что имено тебе надо вставить?
Anatoly Podgoretsky (2006-02-21 19:56:00) [19]SELECT @@IDENTITY