|
|
su.dbms.sql- SU.DBMS.SQL ------------------------------------------------------------------ From : Tolik Gusin 2:5020/400 09 Apr 2001 19:41:20 To : All Subject : Re: Дремина хитрость 2 --------------------------------------------------------------------------------
Hi Ilya,
> IMHO лучше IDENTITY ничего нет. У нас в Sybase есть одно неудобство,
> с ним связанное, которое просто сводит на нет возможность его применения.
> Если бы не оно - везде бы применяли его.
> Это самый лучший и штатный способ генерации ключей.
ИМHО IDENTITY имеет два серьезных недостатка. Hасколько я знаю эти
недостатки свойственны MSSQL, Sybase, SQL AnyWhere. Если это не так, я
бы
очень хотел услышать опровержение этого.
Именно из за указаных мною недостатков IDENTITY хуже последовательностей
как например в Oracle или генераторов как в IB.
1) Есть таблица MASTER. Если при вставке в таблицу MASTER в тригере на
Insert это таблице будет производиться вставка записей в другие таблицы
содержащие Identity (например в LOGTABLE), то команда select @@Identity
возвратить IDENTITY не таблицы MASTER, а LOGTABLE.
2) Есть у нас связка таблиц MASTER-DETAIL. Они связаны как
One Master-Many Detail. Ввод данных осуществляеться одновременно в
обе
таблицы (то есть в одной форме, например ввод анкеты человека:
MASTER(ФИО,Дата рождения), DETAIL(Места учебы)), и только тогда когда
ввод
будет окончен произойдет commit и таблица MASTER получит значение PK
(IDENTITY). Hо ведь это значение MASTER.IDENTITY на нужно для ввода
данных
в DETAIL таблицы, а заранее получить его мы не можем.
Отсюда два выхода:
1) Делать в MASTER пустую строку что бы получить значение ПК для MASTER,
что бы использовать его в DETAIL. А потом делать update MASTER'a.
2) Делать отдельную таблицу для генерации ключей для MASTER таблицы
(то есть делается имитация последовательностей как например в Oracle или
генераторов как в IB).
Я использую второй вариант.
Таблица где храняться ПК :
CREATE TABLE "DBA"."IDTABLE"(
"TABLENAME" char(15) NOT NULL,
"ID" integer NOT NULL,
PRIMARY KEY ("TABLENAME"))
SP которая увеличивает значение ПК для заданной таблицы и возвращает
очередной ПК. Как видите с помощью ее я могу получить как одно значение
ПК, так и пачку значений ПК. Вызываеться она до начала основной
транзакции.
create procedure "dba".GetHandsID(in cTableName char(15), in nAdd
integer)
result(ID integer)
begin
declare nIdentity integer;
// Блокируем нужную строку в таблице IDTABLE
update "dba".IDTABLE set ID=ID where TABLENAME=cTableName;
// Получить последний ID
select ID into nIdentity from "dba".IDTABLE where
TABLENAME=cTableName;
set nIdentity=nIdentity+nAdd;
update "dba".IDTABLE set ID=nIdentity where TABLENAME=cTableName;
commit work;
// Вернуть ID
select nIdentity as ID
end
А это пример ее вызова из программы. Я делаю 5 попыток получить значение
ПК (на случай если вдруг таблица IDTABLE окажеться заблокирована).
function TFirmEditForm.CreateNewID(IsAppend :Boolean) :LongInt;
var
I :Integer;
begin
Result := -1;
if IsAppend then begin
for I := 1 to 5 do
with MainDataModule.WorkDataSet do begin
Close;
SQL.Clear;
SQL.Add('call dba.GetHandsID('+CreateStr('FIRM')+')');
try
Open;
Result := FieldByName('ID').AsInteger;
Break;
except
on E :ENativeDataSetError do begin
if E.ErrorCode = -210 then begin
MainDataModule.ExWorkException(Self,E,'Ошибка при получении
'+
'ID для FIRM, попытка
'+IntToStr(I),1);
end; { if }
end; { except }
end; { try }
end; { with }
MainDataModule.WorkDataSet.Close;
end else
Result :=
MainDataModule.FirmDataSet.FieldByName('IDENTITY').AsInteger;
end; { CreateNewID }
ИМHО вся эта конструкции работает очень быстро и шанс что таблицы
IDTABLE
окажеться заблокирована мизирно мал. Что бы это произошло должны быть
сотни, если не тысячи пользователей которые к тому же без перерыва
молотят данные.
--
С Уважением, Stalker E-mail: stalker732_4@yahoo.com
stalker4@mail.ru
FIDO: 2:464/732.4
ICQ: 28177787
Origin: The History is Dead
--- ifmail v.2.15dev5
* Origin: Alkar Teleport News Server (2:5020/400)
Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /su.dbms.sql/40832144db4d.html, оценка из 5, голосов 10
|