{ **** UBPFD *********** by delphibase.endimus.com ****
>> Назначение прав пользователей на таблицу

Какое может быть описание? И так все понятно. Кто делает эти формы?

Зависимости: uses IBQuery,IBDataBase,SysUtils
Автор: Dracula, dracula@krruda.dp.ua, Krivoy Rog
Copyright: Dracula
Дата: 28 января 2003 г.
***************************************************** }

unit IBRights;
interface

uses IBQuery, IBDataBase, SysUtils;

type
TIBUserRights = record
sel: Boolean;
ins: Boolean;
upd: Boolean;
del: Boolean;
exe: Boolean;
end;

function GetUserRights(UserName, Relation: string; IBDb: TIBDataBase):
TIBUserRights;
var
Rights: TIBUserRights;

implementation

function GetUserRights(UserName, Relation: string; IBDb: TIBDataBase):
TIBUserRights;
var
Qr: TIBQuery;
Tr: TIBTransaction;
begin
if Assigned(IBDb) then
begin
Tr := TIBTransaction.Create(nil);
try
Tr.DefaultDatabase := IBDb;
Qr := TIBQuery.Create(nil);
Qr.Database := IBDb;
Tr.StartTransaction;
Qr.Close;
Qr.Sql.Clear;
Qr.Sql.Add(’select RDB$USER,RDB$PRIVILEGE,RDB$RELATION_NAME ‘ +
‘from RDB$USER_PRIVILEGES ‘ +
‘where upper(RDB$USER)=:AUser ‘ +
‘and upper(RDB$RELATION_NAME)=:ARelation’);
Qr.Prepare;
Qr.Params.ParamValues[’AUser’] := AnsiUpperCase(UserName);
Qr.Params.ParamValues[’ARelation’] := AnsiUpperCase(Relation);
Qr.Open;
while not Qr.eof do
begin
if Copy(Trim(Qr.FieldByName(’RDB$PRIVILEGE’).AsString), 1, 1) = ‘S’ then
Rights.sel := true
else
Rights.sel := false;
if Copy(Trim(Qr.FieldByName(’RDB$PRIVILEGE’).AsString), 1, 1) = ‘I’ then
Rights.ins := true
else
Rights.ins := false;
if Copy(Trim(Qr.FieldByName(’RDB$PRIVILEGE’).AsString), 1, 1) = ‘U’ then
Rights.upd := true
else
Rights.upd := false;
if Copy(Trim(Qr.FieldByName(’RDB$PRIVILEGE’).AsString), 1, 1) = ‘D’ then
Rights.del := true
else
Rights.del := false;
if Copy(Trim(Qr.FieldByName(’RDB$PRIVILEGE’).AsString), 1, 1) = ‘X’ then
Rights.exe := true
else
Rights.exe := false;
if Copy(Trim(Qr.FieldByName(’RDB$PRIVILEGE’).AsString), 1, 1) = ‘R’ then
//Rights.ref:=true else Rights.ref:=false;
begin
Rights.sel := true;
Rights.ins := true;
Rights.upd := true;
Rights.del := true;
Rights.exe := true;
end;
Qr.Next;
end;
Qr.Close;
Tr.Commit;
Qr.Free;
finally
Tr.Free;
end;
end;
Result := Rights;
end;

end.
Пример использования:

uses….., IBRights;
……
var
rights: TIBUserRights;

implementation
…..
begin

rights := GetUserRights(DllLogin, NameTable, IBDataBase);
…..
end;

procedure TForm1.ReadOLE;
var
BS: TBlobStream;
begin
BS := TBlobStream.Create(Table1BLOBFIELD_BLOB, bmRead);
OLEContainer1.LoadFromStream(BS);
BS.Free;
end;

procedure TForm1.WriteOLE;
var
BS: TBlobStream;
begin
BS := TBlobStream.Create(Table1BLOBFIELD_BLOB, bmWrite);
OLEContainer1.SaveToStream(BS);
BS.Free;
end;

Я пытаюсь сгенерировать последовательный ключ для первичной ключевой колонки, но LIBS мне отвечает “nested select is not support in this context.” (вложенный выбор не поддерживается в данном контексте.)

Как насчет:

CREATE TRIGGER AUTOINCREMENT FOR MYTABLE
BEFORE INSERT AS
DECLARE VARIABLE new_key INTEGER;
BEGIN
UPDATE AUTOKEYS
SET KEY_VALUE = KEY_VALUE + 1
WHERE (KEY_ID = “A”);
SELECT KEY_VALUE
FROM AUTOKEYS
WHERE KEY_ID = “A”
INTO :new_key;
new.my_key_column = new_key;
END ^

Я пытаюсь добавить запись в таблицу InterBase, содержащую триггеры и blob-поля, тем не менее, всякий раз при выполнении метода “post” после установки (”append”) значений, я получаю ошибку: ‘Record/Key deleted.’ (запись/ключ удален).

Вот реальный пример того, как я обошел эту проблему:

Определение хранимой процедуры:

Create Procedure NewEmployeeKey Returns ( EmployeeKey Integer ) as
begin
EmployeeKey = Gen_Id( gnEmployeeKey, 1 ) ;
end
Определение триггера:
Create Trigger SetEmployeeKey for tbEmployee Active Before Insert Position 0 as
begin
if ( New.EmployeeKey is Null ) then begin
Execute Procedure NewEmployeeKey Returning_Values New.EmployeeKey ;
end
end
Код Delphi для использования в обработчике события OnNewRecord, или AfterInsert, или BeforePost:

{ qyProviderData - это tQuery }
{ spProviderKey - это tStoredProc }

if qyProviderData.State in [dsInsert] then
begin
spProviderKey.ExecProc ;
qyProviderData.FieldByName( ‘ProviderKey’ ).AsInteger :=
spProviderKey.ParamByName( ‘ProviderKey’ ).AsInteger ;
end ; { if }

Это все, что вам необходимо. Хранимая процедура возвращает следующее сгенерированное значение. Триггер это гарантирует, даже если бы данные не были доступны из вашей Delphi-программы, первичный ключ все еще назначает значение. В Delphi-коде, я полагаю, вы могли бы проверять наличие пустого поля первичного ключа вместо .State in [dsInsert], хотя это то же работает.

Оказывается, что Interbase триггер “before insert” срабатывает только после того, как запись “запостится” из Delphi приложения. В связи с чем становится невозможным увеличение автоинкрементальных ключевых полей. Есть решение?

Большинство программистов решило эту проблему созданием хранимой процедуры (stored procedure), позволяющей от InterBase получить следующий номер и поместить его в вашу запись посредством метода onBeforePost или onNewRecord.