Создаю БД в 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