Создаю БД в C:\dbase1\TELEFON.GDB . Запускаю IBConsole.exe . Далее:
Создаю хранимую процедуру (ввожу как запрос):
SET TERM ^ ;
Create procedure pay_schet(Kod_clienta smallint)
Returns (Data2 char(10), Oplatil float)
AS
Begin
For select Data, VNESENO from OPLATA
where KODCLI = :Kod_clienta
into :Data2, :Oplatil
Do suspend;
End
^
SET TERM ; ^
В метаданных это автоматически разбито на несколько команд.
Создал (IBConsole | Server | User Security ) пользователей:
USER1 пароль = user1, USER2 пароль = user2, USER3 пароль = user3.
Выделяю права пользователям. Ввожу как запросы (при активной БД telefon ):
GRANT ALL ON Client TO User1
GRANT ALL ON OPLATA TO User1
GRANT SELECT ON CLIENT TO User2
GRANT EXECUTE ON PROCEDURE pay_schet TO User1
GRANT SELECT ON OPLATA TO User3
Примечание:
Для удаления прав пользователей – REVOKE, например:
REVOKE ALL ON OPLATA FROM User3
REVOKE UPDATE ON OPLATA FROM User3
--- Метаданные: ---
SET SQL DIALECT 3;
/* CREATE DATABASE 'c:\dbase1\telefon.gdb' PAGE_SIZE 4096
DEFAULT CHARACTER SET WIN1251 */
/* Table: CLIENT, Owner: SYSDBA */
CREATE TABLE "CLIENT"
(
"KODCLI" SMALLINT NOT NULL,
"NOMTEL" CHAR(10) CHARACTER SET WIN1251 NOT NULL,
"FIO" CHAR(30) CHARACTER SET WIN1251 NOT NULL COLLATE PXW_CYRL,
"ADRES" CHAR(30) CHARACTER SET WIN1251 NOT NULL COLLATE PXW_CYRL,
"PASP" CHAR(15) CHARACTER SET WIN1251 NOT NULL COLLATE PXW_CYRL,
"DATANAC" CHAR(10) CHARACTER SET WIN1251 NOT NULL,
PRIMARY KEY ("KODCLI")
);
/* Table: OPLATA, Owner: SYSDBA */
CREATE TABLE "OPLATA"
(
"NOMSCET" SMALLINT NOT NULL,
"KODCLI" SMALLINT NOT NULL,
"DATA" CHAR(10) CHARACTER SET WIN1251 NOT NULL,
"SUMMEJD" FLOAT NOT NULL,
"SUMOBSC" FLOAT NOT NULL,
"DOLG" SMALLINT NOT NULL,
"VNESENO" FLOAT NOT NULL,
PRIMARY KEY ("NOMSCET")
);
ALTER TABLE "OPLATA" ADD FOREIGN KEY ("KODCLI") REFERENCES CLIENT ("KODCLI");
COMMIT WORK;
SET AUTODDL OFF;
SET TERM ^ ;
/* Stored procedures */
CREATE PROCEDURE "PAY_SCHET"
(
"KOD_CLIENTA" SMALLINT
)
RETURNS
(
"DATA2" CHAR(10) CHARACTER SET WIN1251,
"OPLATIL" FLOAT
)
AS
BEGIN EXIT; END ^
ALTER PROCEDURE "PAY_SCHET"
(
"KOD_CLIENTA" SMALLINT
)
RETURNS
(
"DATA2" CHAR(10) CHARACTER SET WIN1251,
"OPLATIL" FLOAT
)
AS
Begin
For select Data, VNESENO from OPLATA
where KODCLI = :Kod_clienta
into :Data2, :Oplatil
Do suspend;
End
^
SET TERM ; ^
COMMIT WORK;
SET AUTODDL ON;
/* Grant Roles for this database */
/* Grant permissions for this database */
GRANT DELETE, INSERT, SELECT, UPDATE, REFERENCES ON "CLIENT" TO USER1;
GRANT SELECT ON "CLIENT" TO USER2;
GRANT DELETE, INSERT, SELECT, UPDATE, REFERENCES ON "OPLATA" TO USER1;
GRANT SELECT ON "OPLATA" TO USER3;
GRANT EXECUTE ON PROCEDURE "PAY_SCHET" TO USER1;
IBDatabase1, IBTransaction1, - для работы с БД, IBTable1, DataSourse1, DBGrid1, DBNavigator1 - для работы с таблицами. IBQuery1, DataSourse2, DBGrid2, IBStoredProc1 - для просмотра результатов хранимой процедуры pay_schet.
IBDatabase1.DefaultTransaction = IBTransaction1, IBTransaction1.Default = IBDatabase1, (установлено IBTransaction1 ReadCommited) IBDatabase1.Connected = true; IBTransaction1.Active = true; IBTable1.Database = IBDatabase1; DataSourse1.DataSet = IBTable1; DBGrid1.DataSourse = DataSourse1; DBNavigator1.DataSourse = DataSourse1; IBQuery1.Database = IBDatabase1; DataSourse2.DataSet = пусто; DBGrid2.DataSourse = пусто; IBStoredProc1.Database = IBDatabase1 (выбирается); IBStoredProc1.StoredProcName = PAY_SCHET (выбирается); IBQuery1.SQL = select data2 as "Дата", oplatil as "Оплатил" from pay_schet(:Kod_clienta) Примечание: в этом проекте изменения записываются в БД при закрытии приложения.
unit unTelefon;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, DBGrids, DB, IBCustomDataSet, IBTable, IBDatabase,
StdCtrls, ExtCtrls, Menus, DBCtrls, IBStoredProc, IBQuery;
type
TForm1 = class(TForm)
IBDatabase1: TIBDatabase;
IBTransaction1: TIBTransaction;
IBTable1: TIBTable;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
RG1: TRadioGroup;
MainMenu1: TMainMenu;
N1: TMenuItem;
N5: TMenuItem;
DBNavigator1: TDBNavigator;
IBStoredProc1: TIBStoredProc;
IBQuery1: TIBQuery;
DataSource2: TDataSource;
DBGrid2: TDBGrid;
Button1: TButton;
procedure RG1Click(Sender: TObject);
procedure N2Click(Sender: TObject);
procedure N4Click(Sender: TObject);
procedure FormActivate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
procedure loga;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
var us: string; itind: integer;
procedure TForm1.RG1Click(Sender: TObject);
begin
IBTable1.Active:= false;
case RG1.ItemIndex of
0: if (uppercase(us)<>'USER3')
then IBTable1.TableName:= 'CLIENT' else
begin
showmessage('Этому юзеру эта таблица недоступна');
RG1.ItemIndex:= -1;
end;
1: if (uppercase(us)<>'USER2')
then IBTable1.TableName:= 'OPLATA' else
begin
showmessage('Этому юзеру эта таблица недоступна');
RG1.ItemIndex:= -1;
end;
end;
try
IBTable1.Active:= true;
except
showmessage('Возможно - нет прав для этого действия');
end;
end;
procedure TForm1.N2Click(Sender: TObject);
begin
Application.Terminate;
end;
procedure TForm1.loga;
var poza,len: integer;
begin
len:= length(IBDataBase1.Params[1]);
poza:= pos('=',IBDataBase1.Params[1]);
us:= copy(IBDataBase1.Params[1],poza+1,len-poza);
IBTable1.Active:= false;
if (uppercase(us)='USER2') then
begin
IBTable1.TableName:= 'CLIENT';
RG1.ItemIndex:= 0;
end;
if (uppercase(us)='USER1') or (uppercase(us)='SYSDBA')
then
begin
IBTable1.ReadOnly:= false;
IBQuery1.Database:= IBDataBase1;
IBQuery1.Active:=true;
DataSource2.DataSet:= IBQuery1;
DBGrid2.DataSource:= DataSource2;
end
else
begin
IBTable1.Active:=false;
IBTable1.ReadOnly:= true;
IBTable1.Active:=true;
end;
IBTable1.Active:=true;
Caption:= 'Телефон ' + us;
end;
procedure TForm1.N4Click(Sender: TObject);
begin
ShowMessage(
'DELETE, INSERT, SELECT, UPDATE, REFERENCES ON "CLIENT" TO USER1'#13#10
+'DELETE, INSERT, SELECT, UPDATE, REFERENCES ON "OPLATA" TO USER1'#13#10
+'SELECT ON "CLIENT" TO USER2'#13#10
+'UPDATE ("VNESENO") ON "OPLATA" TO USER3'#13#10
+'SELECT ON "OPLATA" TO USER3'#13#10
+'EXECUTE ON PROCEDURE "PAY_SCHET" TO USER1'#13#10
+'ALL TO SYSDBA'#13#10
+'Пароли - USER1: user1, USER2: user2, USER3: user3');
end;
procedure TForm1.FormActivate(Sender: TObject);
begin
loga;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if RG1.ItemIndex = 0 then
begin
IBQuery1.Close;
IBQuery1.ParamByName('Kod_clienta').Value:=
IBTable1.Fields[0].Value;
IBQuery1.Open;
end
else
showmessage('Выберите таблицу Клиент');
end;
end.
Скачать все файлы делфи-проекта и файл БД - TELEFON.GDB