Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Значение автоинкремнтного поля и 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


Наверх

Титульная страница Поиск, карта сайта Написать письмо