p align="left">CREATE PROCEDURE NEW_PROCEDURE returns (kld numeric(15,0),movie varchar(50), famio varchar(50)) as declare variable idm integer; declare variable cl integer; declare variable dt date; beginfor select deal.cl_id, deal.d_d, deal.id_mfrom dealinto:cl,:dt,:idmdobeginkld = current_date - dt;if (:kld > 12) thenbeginselect client.fio from client where client.id_c =:clinto:famio;select movie.name_film from movie where movie.id =:idminto:movie;suspend;end end end^Инструкция пользователяПользовательский интерфейс построен в соответствии с классическими требованиями и правилами системы Windows, правилами системы Delphi. Основными задачами при построении интерфейса были: простота, удобство. Программный проект включает в себя 7 оконных форм (одна из них форма главного меню), 4 из них являются непосредственно рабочими (т.е. здесь происходит ввод, обработка и корректирование данных), 3 - формы отображения обработанных данных. При открытие программы появляется главная форма (fmMain) (Рис. 1), на которой расположены таблицы и соответствующие им элементы управления. Если есть задолжники, у которых на руках находятся диски, то вместе с главной формой появляется дочерняя форма «Задолжники»где можно увидеть наименование диска и данные задолжника и количество дней. Для удобства пользователя главная форма содержит несколько вкладок, где и находятся таблицы. Работать с базой можно как непосредственно из главной формы, так и вызвав отдельное окно из главного меню формы. Так пункт меню «Файл» содержит такие подпункты как «Новое» и «Выход». Сделать новую запись в таблице Клиенты(CLIENT) можно выбрав «Файл» -> «Новое..» -> «Клиент». После чего появится окно «Клиент» (Рис. 2), где пользователю представляется возможность заполнения каждого из предложенного полей. Кнопки «Удалить» и «Исправить» в режиме вставки не активны. Процесс редактирования данных происходит в том же самом окне, при выборе меню «Правка» -> «Изменить..» -> «Клиент». В этом же окне появляются уведомления пользователя о недопустимых ошибках. В таблице Клиенты(CLIENT) обязательно для заполнения поле ID_C, если пользователь забывает заполнить это поле, программа уведомит его об этом. Кнопка «Удалить» позволяет удалить запись из базы. Нельзя удалить данные о клиенте, если в таблице «Счета» есть связанные с ним записи, программа предупреждает об этом пользователя, показывая соответствующее сообщение (Рис. 4). В режиме изменение неактивна кнопка «Запись» и появляется дополнительная панель с кнопками навигации по таблице. И, наконец, для завершения работы с формой «Клиент» нужно нажать кнопку закрытия окна, и пользователь попадает на форму главного меню. При редактировании таблицы Фильмы пользователю нужно учитывать, что невозможно удалить данные о фильме, если его количество на складе больше 0. При выборе пункта меню «Счёт» или соответствующей вкладки главной формы пользователь может работать со счетами клиентов. При появлении окна «Новое..» -> «Счёт» пользователь должен ввести штрих код фильма и выбрать фамилию клиента, остальные поля заполняются автоматически (поля - стоимость и дата и возврат). Дата выставляется текущая, а поле стоимость изначально берется из таблицы MOVIE а потом высчитывается с учетом скидок клиенту, возврату автоматически присваивается “N”. Когда клиент возвращает фильм, то следует поставить в этом поле “Y” в ручную или через сканер. При этом количество фильмов в базе увеличивается на 1. На вкладке Счета также есть кнопки «Режим master detail» и «Cведенная таблица». При нажатии на кнопку «Сведенная таблица». Появляется окно с этой таблицей, которая является аналогом таблицы «Счета». Такая таблица может только отображать данные, редактировать их невозможно. Удобство её заключено в том, что листаться она будет заметно быстрее. Листание полного экрана таблицы состоящей из тысячи записей происходит в доли секунды, в то время как таблица «Счета» листается с заметными задержками. Кнопкой «Режим master detail» можно вызвать окно, где пользователь может одновременно просматривать и редактировать данные о клиенте и его счетах. Выбрав меню «Поиск» можно задействовать поиск по таблицам. Поиск по строковому полю позволяет искать по части слова и показывает все формы этого слова. Последняя вкладка «SQL» (Рис. 5) позволяет продвинутым пользователям выполнять различные действия с базой данных, такие как поиск, выборка данный и т.д. Менеджеру будет удобнее просматривать отчёты используя привычный Excel. Для удобства менеджера в Excel есть отчёты по заказам за период, отчёт по персоналу, поиск лучшего клиента месяца и т.д. При этом не требуется устанавливать на машину клиентское приложение. Список литературы Фаронов В.В. Delphi 5. Руководство программиста. Нолидж. 2001. Фаронов ВВ. Delphi 2005 Разработка приложений для баз данных и интернета. -- СПб: Питер, 2006. Хансен Г., Хансен Д. Базы данных. Разработка и управление. -- М., Бином. 2000. ПриложениеЛистинг программыUnit2: interface usesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, DB, IBCustomDataSet, Grids, DBGrids, StdCtrls, ExtCtrls, DBCtrls,ComCtrls, IBTable, XPMan, Menus, IBQuery; typeTForm2 = class(TForm)DBGrid1: TDBGrid;DataSource1: TDataSource;Button1: TButton;PageControl1: TPageControl;TabSheet1: TTabSheet;TabSheet2: TTabSheet;TabSheet3: TTabSheet;DBNavigator1: TDBNavigator;DBGrid2: TDBGrid;DataSource2: TDataSource;Button2: TButton;DBNavigator2: TDBNavigator;DBGrid3: TDBGrid;Panel1: TPanel;DataSource3: TDataSource;Button3: TButton;TabSheet4: TTabSheet;XPManifest1: TXPManifest;Button4: TButton;MainMenu1: TMainMenu;N1: TMenuItem;N2: TMenuItem;N4: TMenuItem;N5: TMenuItem;N6: TMenuItem;N3: TMenuItem;N7: TMenuItem;N8: TMenuItem;N9: TMenuItem;About1: TMenuItem;N10: TMenuItem;N11: TMenuItem;N12: TMenuItem;N13: TMenuItem;N14: TMenuItem;DBGrid4: TDBGrid;Edit1: TEdit;IBQuery1: TIBQuery;DataSource4: TDataSource;procedure Button4Click(Sender: TObject);procedure N12Click(Sender: TObject);procedure N6Click(Sender: TObject);procedure N4Click(Sender: TObject);procedure N3Click(Sender: TObject);procedure Button3Click(Sender: TObject);procedure Button2Click(Sender: TObject);procedure Button1Click(Sender: TObject);private{ Private declarations }public{ Public declarations }end; varForm2: TForm2; implementation uses Unit3, Unit1, Unit4, Unit5, Unit6; {$R *.dfm} procedure TForm2.Button1Click(Sender: TObject); begin Form1.Show; end; procedure TForm2.Button2Click(Sender: TObject); begin try DataSource1.DataSet.Delete; except ShowMessage('Нельзя удалить данные о клиенте если в таблице База есть связанные записи!'); end; end; procedure TForm2.Button3Click(Sender: TObject); begin Form4.Show; end; procedure TForm2.N3Click(Sender: TObject); begin Form2.Close; end; procedure TForm2.N4Click(Sender: TObject); begin Form5.Show; Form5.Button1.Enabled:=true; Form5.Panel2.Visible:=false; Form5.Button3.Enabled:=false; Form5.Button4.Enabled:=false; end; procedure TForm2.N6Click(Sender: TObject); beginForm6.Show;end; procedure TForm2.N12Click(Sender: TObject); begin Form5.Show; Form5.Button1.Enabled:=false; DataSource1.DataSet.Cancel; DataSource1.DataSet.First; Form5.Panel2.Visible:=true; Form5.Button3.Enabled:=true; Form5.Button4.Enabled:=true; end; procedure TForm2.Button4Click(Sender: TObject); begin if Edit1.Text <>'' then begin IbQuery1.SQL.Text:=Edit1.Text; Form2.DataSource4.DataSet.Active:=true; end else ShowMessage('Пустой запрос!'); end; end. Unit4: unit Unit4; interface usesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls, DB, Grids, DBGrids, IBCustomDataSet; typeTForm4 = class(TForm)IBDataSet1: TIBDataSet;DBGrid1: TDBGrid;DBGrid2: TDBGrid;DataSource1: TDataSource;DataSource2: TDataSource;CheckBox1: TCheckBox;procedure CheckBox1Click(Sender: TObject);private{ Private declarations }public{ Public declarations }end; varForm4: TForm4; implementation uses Unit2, Unit3; {$R *.dfm} procedure TForm4.CheckBox1Click(Sender: TObject); beginif CheckBox1.State = cbchecked then begin DataModule3.IBDataSet1.Active:=False; Form4.IBDataSet1.SelectSQL.SetText('SELECT * FROM DEAL WHERE CL_ID =:ID_C');Form4.IBDataSet1.Open; DataModule3.IBDataSet1.Open; end else begin Form4.IBDataSet1.Close; DataModule3.IBDataSet1.Close; Form4.IBDataSet1.SelectSQL.SetText('SELECT * FROM DEAL'); Form4.IBDataSet1.Active:=True; DataModule3.IBDataSet1.Active:=True; end; end; end. Unit5: unit Unit5; interface usesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, ExtCtrls, StdCtrls, DBCtrls, Mask, DB, IBCustomDataSet; typeTForm5 = class(TForm)DBEdit1: TDBEdit;Label1: TLabel;Label2: TLabel;Button1: TButton;Button2: TButton;Panel1: TPanel;DBMemo1: TDBMemo;DataSource1: TDataSource;Panel2: TPanel;Button3: TButton;Button4: TButton;Button5: TButton;Button6: TButton;procedure Button6Click(Sender: TObject);procedure Button5Click(Sender: TObject);procedure Button4Click(Sender: TObject);procedure FormClose(Sender: TObject; var Action: TCloseAction);procedure FormShow(Sender: TObject);procedure Button3Click(Sender: TObject);procedure Button2Click(Sender: TObject);procedure Button1Click(Sender: TObject);private{ Private declarations }public{ Public declarations }end; varForm5: TForm5; implementation uses Unit2, Unit4, Unit1, Unit3; {$R *.dfm} procedure TForm5.Button1Click(Sender: TObject); var name,p:string; begin name:=DbEdit1.Text; p:= DbMemo1.Text; tryDataSource1.DataSet.FieldByName('FIO').AsString:=name;DataSource1.DataSet.FieldByName('PASPORT').AsString:=p;DataSource1.DataSet.Post;DataSource1.DataSet.Append;except ShowMessage('Поле ФИО обязательно для заполнения'); end; end; procedure TForm5.Button2Click(Sender: TObject); begin DbEdit1.Clear; DbMemo1.Clear; end; procedure TForm5.Button3Click(Sender: TObject); begintry Form2.DataSource1.DataSet.Delete; except ShowMessage('Нельзя удалить данные о клиенте если в таблице База есть связанные записи!'); end; end; procedure TForm5.FormShow(Sender: TObject); begin DataSource1.DataSet.Append; end; procedure TForm5.FormClose(Sender: TObject; var Action: TCloseAction); begin DataSource1.DataSet.Cancel; end; procedure TForm5.Button4Click(Sender: TObject); begin Form2.DataSource1.DataSet.Post; end; procedure TForm5.Button5Click(Sender: TObject); begin Form2.DataSource1.DataSet.Prior; end; procedure TForm5.Button6Click(Sender: TObject); beginForm2.DataSource1.DataSet.Next; end; end. Unit6: interface usesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, DB, DBCtrls, StdCtrls, IBCustomDataSet, IBQuery, Mask; typeTForm6 = class(TForm)DBLookupComboBox1: TDBLookupComboBox;DataSource1: TDataSource;Edit1: TEdit;Button1: TButton;Label1: TLabel;Label2: TLabel;IBQuery1: TIBQuery;DataSource2: TDataSource;DBEdit1: TDBEdit;procedure FormClose(Sender: TObject; var Action: TCloseAction);procedure Button1Click(Sender: TObject);procedure FormShow(Sender: TObject);private{ Private declarations }public{ Public declarations }end; varForm6: TForm6;s:string; implementation uses Unit3; {$R *.dfm} procedure TForm6.FormShow(Sender: TObject); beginDataSource1.DataSet.Append; end; procedure TForm6.Button1Click(Sender: TObject); var s: string; beginForm6.IBQuery1.Active:=false;s:='select MONEY from movie where movie.id = '+ Edit1.Text;Form6.IBQuery1.SQL.text:=s;Form6.IBQuery1.Active:=true;Form6.DBEdit1.DataField:='MONEY';DataSource1.DataSet.FieldByName('DEN').AsString:=Form6.DBEdit1.Text;DataSource1.DataSet.FieldByName('ID_M').AsString:=Edit1.Text;DataSource1.DataSet.Post;DataSource1.DataSet.Append;end; procedure TForm6.FormClose(Sender: TObject; var Action: TCloseAction); beginDataSource1.DataSet.Cancel; end; end. Unit7: interface usesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls; typeTForm7 = class(TForm)ComboBox1: TComboBox;Button1: TButton;Edit1: TEdit;ComboBox2: TComboBox;procedure ComboBox2Change(Sender: TObject);procedure Button1Click(Sender: TObject);procedure ComboBox1Change(Sender: TObject);private{ Private declarations }public{ Public declarations }end; varForm7: TForm7;tb,k:string; implementation uses Unit2; {$R *.dfm} procedure TForm7.ComboBox1Change(Sender: TObject); begin if Combobox1.Items.Strings[Combobox1.ItemIndex]='Фильмы' then begin tb:='MOVIE'; Combobox2.Items.Clear; Combobox2.Items.Add('ID'); Combobox2.Items.Add('NAME_FILM'); Combobox2.Items.Add('DIRECTOR'); Combobox2.Items.Add('KOL'); Combobox2.Items.Add('MONEY'); Combobox2.Items.Add('GANR'); Combobox2.Items.Add('DESCRIPTION'); end elsebegintb:='CLIENT';Combobox2.Items.Clear;Combobox2.Items.Add('ID_C');Combobox2.Items.Add('FIO');Combobox2.Items.Add('PASPORT');end; if Combobox1.Items.Strings[Combobox1.ItemIndex]='Счета' thenbegintb:='DEAL';Combobox2.Items.Clear;Combobox2.Items.Add('ID_D'); Combobox2.Items.Add('ID_M');Combobox2.Items.Add('CL_ID'); Combobox2.Items.Add('DEN');Combobox2.Items.Add('D_D');end;end; procedure TForm7.Button1Click(Sender: TObject); var zapros: string; beginif (k = 'ID_C') or (k = 'ID') or (k = 'ID_D') or(k='KOL') or (k='MONEY') or(k='ID_M') or (k='CL_ID')thenzapros:='SELECT * from '+tb+' where '+k+'='+Edit1.Textelsezapros:='SELECT * from '+tb+' where '+k+' LIKE '+'''%'+Edit1.Text+'%''';Form2.IBQuery1.SQL.Text:=zapros;Form2.DataSource4.DataSet.Active:=true;Form7.Close;Form2.PageControl1.ActivePage:= Form2.PageControl1.Pages[4];Form2.FocusControl(Form2.PageControl1); end; procedure TForm7.ComboBox2Change(Sender: TObject); begink:=Combobox2.Items.Strings[Combobox2.ItemIndex]; end; end. Скрипты: DOMAINS: CREATE DOMAIN D_GANR AS VARCHAR(10) CHARACTER SET NONE NOT NULL CHECK (VALUE IN ('comedy', 'action', 'melodramm', 'fantasy', 'horror')) COLLATE NONE Tables: CLIENT: /******************************************************************************/ /**** Tables ****//******************************************************************************/ CREATE GENERATOR GEN_CLIENT_ID_C; CREATE TABLE CLIENT (ID_C INTEGER,FIO VARCHAR(50) NOT NULL,PASPORT VARCHAR(50)); /******************************************************************************/ /**** Primary Keys ****//******************************************************************************/ ALTER TABLE CLIENT ADD PRIMARY KEY (ID_C); /******************************************************************************/ /**** Triggers ****//******************************************************************************/ SET TERM ^;/******************************************************************************/ /**** Triggers for tables ****//******************************************************************************/ /* Trigger: TRIG_CLIENT */ CREATE TRIGGER TRIG_CLIENT FOR CLIENT ACTIVE BEFORE INSERT POSITION 0 AS BEGINIF (NEW.id_c IS NULL) THEN NEW.id_c = GEN_ID(gen_client_id_c,1); END ^ DEAL: /******************************************************************************/ /**** Tables ****//******************************************************************************/ CREATE GENERATOR GEN_DEAL_ID; CREATE TABLE DEAL (ID_D INTEGER,ID_M INTEGER NOT NULL,CL_ID INTEGER NOT NULL,DEN NUMERIC(4,2),D_D DATE); /******************************************************************************/ /**** Primary Keys ****//******************************************************************************/ ALTER TABLE DEAL ADD PRIMARY KEY (ID_D); /******************************************************************************/ /**** Foreign Keys ****//******************************************************************************/ ALTER TABLE DEAL ADD FOREIGN KEY (CL_ID) REFERENCES CLIENT (ID_C) ON UPDATE CASCADE; ALTER TABLE DEAL ADD FOREIGN KEY (ID_M) REFERENCES MOVIE (ID) ON DELETE CASCADE ON UPDATE CASCADE; /******************************************************************************/ /**** Triggers for tables ****//******************************************************************************/ /* Trigger: DEC_MONEY */ CREATE TRIGGER DEC_MONEY FOR DEAL ACTIVE AFTER INSERT POSITION 0 ASdeclare variable x integer; beginSelect Count(New.cl_id) from DEALinto:x;if (:x > 3) thenbeginupdate Dealset Deal.den = (DEAL.den - DEAL.den/100*10)where DEAL.id_d = New.id_d;end end /* Trigger: SUB_MOVIE */ CREATE TRIGGER SUB_MOVIE FOR DEAL ACTIVE AFTER INSERT POSITION 0 AS beginupdate movieset movie.kol = movie.kol - 1where movie.id = new.id_m; end /* Trigger: TRIG_DEAL_BI */ CREATE TRIGGER TRIG_DEAL_BI FOR DEAL ACTIVE BEFORE INSERT POSITION 0 AS BEGINIF (NEW.Id_d IS NULL) THEN NEW.Id_d = GEN_ID(Gen_DEAL_ID,1); END MOVIE: /******************************************************************************/ /**** Tables ****//******************************************************************************/ CREATE GENERATOR GEN_DEAL_ID; CREATE TABLE DEAL (ID_D INTEGER,ID_M INTEGER NOT NULL,CL_ID INTEGER NOT NULL,DEN NUMERIC(4,2),D_D DATE); /******************************************************************************/ /**** Primary Keys ****//******************************************************************************/ ALTER TABLE DEAL ADD PRIMARY KEY (ID_D); /******************************************************************************/ /**** Foreign Keys ****//******************************************************************************/ ALTER TABLE DEAL ADD FOREIGN KEY (CL_ID) REFERENCES CLIENT (ID_C) ON UPDATE CASCADE; ALTER TABLE DEAL ADD FOREIGN KEY (ID_M) REFERENCES MOVIE (ID) ON DELETE CASCADE ON UPDATE CASCADE; /******************************************************************************/ /**** Triggers for tables ****//******************************************************************************/ /* Trigger: DEC_MONEY */ CREATE TRIGGER DEC_MONEY FOR DEAL ACTIVE AFTER INSERT POSITION 0 ASdeclare variable x integer; beginSelect Count(cl_id) from DEAL where cl_id = New.cl_id group by cl_idinto:x;if (:x > 3) thenbeginupdate Dealset Deal.den = (DEAL.den - DEAL.den/100*10)where DEAL.id_d = New.id_d;end end /* Trigger: SUB_MOVIE */ CREATE TRIGGER SUB_MOVIE FOR DEAL ACTIVE AFTER INSERT POSITION 0 AS beginupdate movieset movie.kol = movie.kol - 1where movie.id = new.id_m; end /* Trigger: TRIG_DEAL_BI */ CREATE TRIGGER TRIG_DEAL_BI FOR DEAL ACTIVE BEFORE INSERT POSITION 0 AS BEGINIF (NEW.Id_d IS NULL) THEN NEW.Id_d = GEN_ID(Gen_DEAL_ID,1); END EXCEPTION: CREATE EXCEPTION NO_DELETE 'Нельзя удалить фильм если он имеется на складе!'; VIEW: CREATE VIEW BESTCLIENT(FIO) AS select FIO from client where id_c =(select cl from(select deal.cl_id as cl, count (cl_id) as col from deal group by deal.cl_id HAVING count (cl_id) >=All (select count (cl_id) as col from deal group by deal.cl_id)));
Страницы: 1, 2, 3, 4
|