11。Lazarus数据库编程9。ZeosDBO与FireBird综合示例
9.ZeosDBO与FireBird综合示例9.1关于 FireBird
Firebird是一个开源的关系数据库,提供了大部分SQL-99标准的功能,可以运行在Windows、linux和多种Unix操作系统上。Firebird提供良好的并发性,高效的执行,强大的语言支持存储过程和触发器。从1981年起,它已经被许多商业公司运用于许多的产品系统中。
Firebird 和原 Borland 的 InterBase 有着相同的血脉,其作为一个开源项目遵循 InterBase Public License V.1.0 on 25 July, 2000 协议。
FireBird 数据库的特点: Firebird是一个真正的关系数据库,支持存储过程、视图、触发器、事务等大型关系数据库的所有特性; Firebird支持SQL92的绝大部分命令,并且支持大部分SQL99命令,新版Firebird 2.0对SQL99的支持更完整; Firebird源码基于成熟的商业数据库 Interbase,有良好的稳定性,与Interbase有良好的兼容性; 不用考虑授权费用(免费),不用担心将来有一天你或你的客户因为使用盗版而被数据库开发商告上法庭; 发布简易,安装文件只有几M,且高度可定制,客户端的分发也很简单,只需一个DLL文件; Firebird 还具有一个嵌入式服务器版本,不用安装,直接运行,基于单机开发首选; Firebird的运行效率非常高; 具备高度可移植性,可在Linux、Unix、MacOS、Windows、Solaris 系统下运行,而且数据库格式完全一致,不用修改; 开发环境支持良好,Delphi、C++Builder不用通过 ODBC 连接,直接用原生开发接口开发出基于 Firebird 的程序;除此之外,对于 Java、Python、.NET、PHP 都具有良好的支持。
FireBird 数据库软件有三种套件,支持不同作业平台(windows系列、linux、freebsd 等...) Super Server - 无法直接存取数据库档案,必须透过socket来和服务器沟通 Classic - 直接存取数据库的档案,多个程序可以同时存取一个档案, 类似于 vfp、dbase embedded - 专为小型应用系统使用的嵌入式数据库 (pda)
另外,新版的 FireBird 数据库软件还支持 Android ARM32、 Android ARM64、 Mac OS X。 9.2 FireBird 开发示例
本节示例:实现对一张数据表的 CRUD 操作,通过两个窗体,其中主窗体展现数据,表单窗体用于录入和修改数据。数据准备如下: create table c_dep ( dep_id varchar(64) primary key, dep_name varchar(16) ); insert into c_dep (dep_id, dep_name) values ("yfb", "研发部"); insert into c_dep (dep_id, dep_name) values ("xsb", "销售部"); insert into c_dep (dep_id, dep_name) values ("jszcb", "技术支持部"); insert into c_dep (dep_id, dep_name) values ("cwb", "财务部"); insert into c_dep (dep_id, dep_name) values ("xzb", "行政部"); create table d_dep_staff ( staff_id varchar(64) primary key, dep_id varchar(64), name varchar(32), sex varchar(8), birthday date, edu_level varchar(16), school varchar(64), speciality varchar(32), native_place varchar(256) ); INSERT INTO d_dep_staff (staff_id, dep_id, name, sex, birthday, edu_level, school, speciality, native_place) VALUES(uuid_to_char(gen_uuid()), "yfb", "张三", "女", "1981-9-10", "本科", "内蒙古大学", "经济管理", "内蒙古乌兰察布市集宁区"); INSERT INTO d_dep_staff (staff_id, dep_id, name, sex, birthday, edu_level, school, speciality, native_place) VALUES(uuid_to_char(gen_uuid()), "xsb", "刘五", "男", "1978-7-11", "本科", "内蒙古大学", "计算机科学与技术", "内蒙古鄂尔多斯市东胜区"); INSERT INTO d_dep_staff (staff_id, dep_id, name, sex, birthday, edu_level, school, speciality, native_place) VALUES(uuid_to_char(gen_uuid()), "xzb", "弓九", "女", "1983-3-10", "本科", "内蒙古科技大学", "计算机科学与技术", "内蒙古呼和浩特市托克托县");
在数据表设计上,我比较习惯于主键使用 UUID,这个习惯也是受近几年的分布式数据库的影响而形成的。在 FireBird 中,对于 UUID 在支持包括如下函数: CHAR_TO_UUID (ascii_uuid) GEN_UUID () UUID_TO_CHAR (uuid)
如: select char_to_uuid("A0bF4E45-3029-2a44-D493-4998c9b439A3") from rdb$database -- returns A0BF4E4530292A44D4934998C9B439A3 (16-byte string) select char_to_uuid("A0bF4E45-3029-2A44-X493-4998c9b439A3") from rdb$database -- error: -Human readable UUID argument for CHAR_TO_UUID must -- have hex digit at position 20 instead of "X (ASCII 88)" select gen_uuid() from rdb$database -- returns e.g. 017347BFE212B2479C00FA4323B36320 (16-byte string) select uuid_to_char(x"876C45F4569B320DBCB4735AC3509E5F") from rdb$database -- returns "876C45F4-569B-320D-BCB4-735AC3509E5F" select uuid_to_char(gen_uuid()) from rdb$database -- returns e.g. "680D946B-45FF-DB4E-B103-BB5711529B86" select uuid_to_char("Firebird swings!") from rdb$database -- returns "46697265-6269-7264-2073-77696E677321"9.3 Lazarus 应用程序示例9.3.1 界面设计
主窗体界面如下图:
表单窗体界面如下图:
9.3.2 数据模块
数据模块组件声明代码: TDataModule1 = class(TDataModule) // 数据库组件 ZConnection1: TZConnection; ZQuery1: TZQuery; // 字段定义 ZQuery1_BIRTHDAY: TDateField; ZQuery1_DEP_ID: TStringField; ZQuery1_DEP_NAME: TStringField; ZQuery1_EDU_LEVEL: TStringField; ZQuery1_NAME: TStringField; ZQuery1_NATIVE_PLACE: TStringField; ZQuery1_SCHOOL: TStringField; ZQuery1_SEX: TStringField; ZQuery1_SPECIALITY: TStringField; ZQuery1_STAFF_ID: TStringField; private public end;
数据库组件属性设置:
组件
属性
值
ZConnection1
Protocol
firebird
HostName
127.0.0.1
Port
3050
User
sysdba
Password
***
Database
E:workspace_of_lazarusDEMODB.FDB
Connected
True
ZQuery1
Connection
ZConnection1
SQL
SELECT staff_id, s.dep_id, name, sex, birthday, edu_level, school, speciality, native_place, d.dep_name FROM d_dep_staff s left join c_dep d on s.dep_id = d.dep_id
Active
True 9.3.3 主窗体组件
主窗体组件声明代码如下: TForm1 = class(TForm) // CRUD 按钮 Button1: TButton; Button2: TButton; Button3: TButton; Button4: TButton; // 数据库组件 DataSource1: TDataSource; DBGrid1: TDBGrid; // 数据导航组件 DBNavigator1: TDBNavigator; // 按钮及数据导航组件容器 Panel1: TPanel; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); procedure DBGrid1DblClick(Sender: TObject); private public end;
主窗体数据库组件的属性:
组件
属性
值
DataSource1
DataSet
DataModule1.ZQuery1
DBNavigator1
DataSource
DataSource1
VisibleButtons
[nbFirst,nbPrior,nbNext,nbLast]
Align
alRight
DBGrid1
DataSource
DataSource1
Options
dgRowSelect=True
Align
alClient 9.3.4 表单窗体组件
表单窗体组件声明代码: TForm2 = class(TForm) // 确定、取消按钮 Button1: TButton; Button2: TButton; // 数据编辑组件 SpecialityEdit: TEdit; SchoolEdit: TEdit; EduLevelComboBox: TComboBox; BirthdayDateTimePicker: TDateTimePicker; DepComboBox: TComboBox; NameEdit: TEdit; NativePlaceEdit: TEdit; SexRadioGroup: TRadioGroup; // 数据标签组件 GroupBox1: TGroupBox; GroupBox2: TGroupBox; GroupBox3: TGroupBox; GroupBox4: TGroupBox; GroupBox5: TGroupBox; GroupBox6: TGroupBox; GroupBox7: TGroupBox; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure FormActivate(Sender: TObject); private public isNew: Boolean; // 标识是否为新建数据记录 end; 9.3.5 主窗体功能实现代码
代码如下: uses unit2, unit3; { TForm1 } procedure TForm1.Button1Click(Sender: TObject); begin // 新建 Form2.isNew := True; if Form2.ShowModal = mrOk then begin DataModule1.ZQuery1.Refresh; end; end; procedure TForm1.Button2Click(Sender: TObject); begin // 编辑 if DataModule1.ZQuery1.BOF then if DataModule1.ZQuery1.RecordCount > 0 then DataModule1.ZQuery1.First else Exit; if DataModule1.ZQuery1.EOF then if DataModule1.ZQuery1.RecordCount > 0 then DataModule1.ZQuery1.Last else Exit; Form2.isNew := False; if Form2.ShowModal = mrOk then begin DataModule1.ZQuery1.Refresh; end; end; procedure TForm1.Button3Click(Sender: TObject); var Query: TZQuery; begin // 删除 if DataModule1.ZQuery1.BOF then if DataModule1.ZQuery1.RecordCount > 0 then DataModule1.ZQuery1.First else Exit; if DataModule1.ZQuery1.EOF then if DataModule1.ZQuery1.RecordCount > 0 then DataModule1.ZQuery1.Last else Exit; Query := TZQuery.Create(Self); try Query.Connection := DataModule1.ZConnection1; Query.Close; Query.SQL.Text := "DELETE FROM d_dep_staff where staff_id = :staffId"; Query.Params.ParamByName("staffId").AsString := DataModule1.ZQuery1_STAFF_ID.Value; Query.ExecSQL; except on D: EDatabaseError do MessageDlg("Error", "A database error has occurred. Technical error message: " + D.Message, mtError, [mbOK], 0); end; Query.Destroy; DataModule1.ZQuery1.Refresh; end; procedure TForm1.Button4Click(Sender: TObject); begin // 刷新 DataModule1.ZQuery1.Refresh; end; procedure TForm1.DBGrid1DblClick(Sender: TObject); begin // 双击修改 Button2Click(Sender); end; 9.3.6 表单窗体功能实现代码
代码如下: uses unit2; { TForm2 } procedure TForm2.Button1Click(Sender: TObject); begin // 取消 ModalResult := mrCancel; end; procedure TForm2.Button2Click(Sender: TObject); var Query: TZQuery; index: Integer; depId: String; begin // 确定 if NameEdit.Text = "" then begin MessageDlg("提示", "请输入姓名!", mtError, [mbOK], 0); Exit; end; if DepComboBox.ItemIndex < 0 then begin MessageDlg("提示", "请选择所在部门!", mtError, [mbOK], 0); Exit; end; index := DepComboBox.ItemIndex; depId := PAnsiString(DepComboBox.Items.Objects[index])^; Query := TZQuery.Create(Self); try Query.Connection := DataModule1.ZConnection1; Query.Close; if isNew then begin Query.SQL.Text := "INSERT INTO d_dep_staff (staff_id, dep_id, name, sex, birthday, edu_level, school, speciality, native_place) VALUES(uuid_to_char(gen_uuid()), :depId, :name, :sex, :birthday, :eduLevel, :school, :speciality, :nativePlace)"; Query.Params.ParamByName("depId").AsString := depId; Query.Params.ParamByName("name").AsString := NameEdit.Text; if SexRadioGroup.ItemIndex = 0 then Query.Params.ParamByName("sex").AsString := "男" else Query.Params.ParamByName("sex").AsString := "女"; Query.Params.ParamByName("birthday").AsDate := BirthdayDateTimePicker.Date; Query.Params.ParamByName("eduLevel").AsString := EduLevelComboBox.Text; Query.Params.ParamByName("school").AsString := SchoolEdit.Text; Query.Params.ParamByName("speciality").AsString := SpecialityEdit.Text; Query.Params.ParamByName("nativePlace").AsString := NativePlaceEdit.Text; Query.ExecSQL; end else begin Query.SQL.Text := "UPDATE d_dep_staff SET dep_id=:depId, name=:name, sex=:sex, birthday=:birthday, edu_level=:eduLevel, school=:school, speciality=:speciality, native_place=:nativePlace WHERE staff_id=:staffId"; Query.Params.ParamByName("depId").AsString := depId; Query.Params.ParamByName("name").AsString := NameEdit.Text; if SexRadioGroup.ItemIndex = 0 then Query.Params.ParamByName("sex").AsString := "男" else Query.Params.ParamByName("sex").AsString := "女"; Query.Params.ParamByName("birthday").AsDate := BirthdayDateTimePicker.Date; Query.Params.ParamByName("eduLevel").AsString := EduLevelComboBox.Text; Query.Params.ParamByName("school").AsString := SchoolEdit.Text; Query.Params.ParamByName("speciality").AsString := SpecialityEdit.Text; Query.Params.ParamByName("nativePlace").AsString := NativePlaceEdit.Text; Query.Params.ParamByName("staffId").AsString := DataModule1.ZQuery1_STAFF_ID.Value; Query.ExecSQL; end; except on D: EDatabaseError do MessageDlg("Error", "A database error has occurred. Technical error message: " + D.Message, mtError, [mbOK], 0); end; Query.Destroy; ModalResult := mrOk; end; procedure TForm2.FormActivate(Sender: TObject); var Query: TZQuery; index: Integer; begin // 初始化部门选项 try Query := TZQuery.Create(Self); Query.Connection := DataModule1.ZConnection1; Query.Close; Query.SQL.Text := "SELECT dep_id, dep_name FROM c_dep"; Query.Open; DepComboBox.Items.Clear; while not Query.EOF do begin DepComboBox.Items.AddObject( Query.FieldByName("dep_name").AsString, TObject(NewStr(Query.FieldByName("dep_id").AsString)) ); Query.Next; end; except on D: EDatabaseError do MessageDlg("Error", "A database error has occurred. Technical error message: " + D.Message, mtError, [mbOK], 0); end; // 初始化数据项 if isNew then begin NameEdit.Text:=""; SexRadioGroup.ItemIndex:=0; SchoolEdit.Text:=""; SpecialityEdit.Text:=""; NativePlaceEdit.Text:=""; end else with DataModule1 do begin NameEdit.Text:=ZQuery1_NAME.Value; if ZQuery1_SEX.Value = "男" then SexRadioGroup.ItemIndex:=0 else SexRadioGroup.ItemIndex:=1; index := DepComboBox.Items.IndexOf(ZQuery1_DEP_NAME.Value); DepComboBox.ItemIndex:=index; BirthdayDateTimePicker.Date := ZQuery1_BIRTHDAY.Value; EduLevelComboBox.Text := ZQuery1_EDU_LEVEL.Value; SchoolEdit.Text := ZQuery1_SCHOOL.Value; SpecialityEdit.Text:=ZQuery1_SPECIALITY.Value; NativePlaceEdit.Text:= ZQuery1_NATIVE_PLACE.Value; end; end;
穷,别信四件事富,不交二种人1只要跟随就能赚钱的事这种天上掉馅饼的事,怎么可能就砸到你的头上呢?特别是这种既不用出力又不用动脑,就能赚钱的好事千万要小心,否则你就会成为待宰的羔羊。因为像跟屁虫一样跟在别人的后
夜读善待父母,是我们一生的功课父母是我们的根。有的人总是在父母面前控制不好情绪,把他们对自己的包容当成理所应当。几乎每个人都会犯这样一个错误面对父母的时候毫无顾忌,什么话都说得出口,但是面对陌生人和朋友却谦逊有
天下霖雨一连下了多日的雨,把里里外外都下潮湿了天下霖雨雨一连下了多日,不停地下,望不到头,想不起它从哪天下起,也看不出它会在哪天结束。四下清冷,内心阴寡,与儿时霖雨中的情形相似。大自然的一切多是踩着点。关中农人在焦火的包谷地里
Python图像处理五。图像融合图像加减法图像逻辑运算也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大少走了弯路,也就错过了风景,无论如何,感谢经历更多关于Android安全的知识,可前往ht
执业医师保健工室三天保健茶合总费用30元。如果有一家保健养生工作室,对病因不清的疾病,对功能性失调疾病,对慢性疾病等调整,并对熬夜毒素,烟酒毒气,痰湿邪物。具有预防免疫性于三高,肥胖,对心肝脾胃肠
多事之秋需提防气象病秋三月雨水渐少天气干燥,昼热夜凉气候寒热多变,若自身正气不足,很容易就会被秋燥秋寒悲秋情绪打垮。多事之秋里我们究竟该如何抵御气象病?秋燥口干眼干舌苔干润燥滋阴治燥邪原本秋天就是个少
国庆颂(新韵外一首)作者宋有荣一hr十月金秋国庆颂,五星旗帜舞东风。神州赤县齐欢唱,塞北江南尽沸腾。新兴大国强起立,文明华夏更繁荣。镰锤引领向前进,复兴航船破浪行。二hr岁月峥嵘雨雪狂,七十三载铸辉煌。科学跃进
惜时如惜命时光一去不复返朱自清先生的散文匆匆把时光的流逝表述的淋漓尽致,表达了他对时光一去不复返的感慨,又体现出他对时间的珍惜之情,甚至希望人如果不吃饭不睡觉该多好!国人几乎都读过这篇文章,
十月,我在深情地凝望作者艳子十月,我在深情地凝望那是一片片金黄色的稻浪捧出了收获的喜悦与希望在岁月静好的流逝里畅想写下了一曲曲清浅的吟唱这才是生活中最美好的模样那一眼望不到头的高粱摇曳着火红的渴望这是
西行漫记第20天一转眼,离家已到了第20天,三分之一的时间过去了,想着接下来尚未履行的三分之二,居然有种想家的感觉了,毕竟这是人生中目前最长久的远行了。独在异乡为异客。在这孤独的日子里,或许是想念
1比2,1比1!中超升班马爆冷,泰山争冠希望重燃,恒大保级迎利好10月4日,中超第21轮比赛开打。在已经结束的4场比赛中,中超领头羊三镇爆冷不敌浙江队,在多赛一场的情况下只领先泰山队4分了,这让后者争冠希望重燃。与此同时,保级圈的广州城1比1战
如何科学保护乳房?人们对疾病的恐惧,往往是患病了才开始痛苦,开始焦虑,开始了解怎么预防疾病。其实,对于疾病,预防比治疗更重要。特别是像乳腺疾病这种慢性病。乳房是女性美丽的象征,但它一旦患病,就会让我
游戏王怪兽卡水族(3)伯吉斯异兽奇虾()曾被称为神的龟(神呼亀)曾被称为神的龟(神呼亀)超无畏军贯海胆级二号舰(超弩級軍貫型二番艦)超无畏军贯海胆级二号舰(超弩級軍貫型二番艦)赤舍利军贯(赤軍貫)赤舍利
请将这十种人,踢出你的朋友圈大家好,麦田里的晚风第282篇文章,记得点赞与关注,不断为你分享生活哲理与乐趣。卢思浩曾说如果没有同行的那个人,索性一个人看风景。除非两个人在一起感觉能更好,否则宁愿一个人生活。我
为爱装傻,狼狈的我像个傻瓜原创孤月冷梅你给我的承诺你已经完全忘记了原来遇见只是在刹那间我可以为爱装傻为爱无法自拔说不出一句只想用一行小字清清浅浅却轻轻拨动心弦那时年轻的我们爱得疯狂也曾痛的喉咙沙哑就算好了伤
我是个软弱的人我知道,我是个软弱的人,我是不爱承认的,当我不勇敢时,我是羞愧的。那试问,又有几个爱文字的人喜欢拔剑弩张,高举拳头呢?所以,有时候我又不愿意承认自己是软弱的,当我全小区开窗高嗓子吼
逆向思维赚钱就是做自己,被人哄着罩着你永远都长不大逆向思维赚钱就是做自己,被人哄着罩着你永远长不大。六祖慧能那句著名偈语说,本来无一物,何处惹尘埃。每个人本质上来到这个世界,就是孤身一人,什么也没有带来,去的时候什么也带不走。所谓
羊了个羊突然爆了!昙花一现还是爆款留存?羊了个羊羊了个羊突然爆了!原因竟然是服务器炸了。网友一脸懵逼,什么羊羊羊,是灰太狼的羊吗?荒漠屠夫现在不是在新疆嘎羊吗,大漠黄沙,和服务器有毛线关系?点进去一看,原来是一个微信小游
平平无奇的羊了个羊,凭什么就爆红了最近,一款名为羊了个羊的微信小游戏可谓是席卷朋友圈,更是在微博热搜榜单榜上有名。截至目前,羊了个羊在微博上已获得了接近7亿阅读量抖音上的相关视频播放量也超过6000万。那么问题就来
合理喂养,让婴幼儿远离缺铁性贫血(特别家教1126期)为了在特殊时期为家长提供特别的家庭教育指导,全国妇联推出了特殊时期特别家教微信栏目,家长可以通过家庭教育微课学习家庭教育知识。合理喂养,让婴幼儿远离缺铁性贫血(特别家教1126期)
让我们一起读书有很多小朋友都不喜欢读书,可是我不一样,我爱读书,从很小开始,就跟书有着深厚的感情。从上幼儿园起,爸爸就买了许多书给我看,从图画书到现在的小说,我看过的书可多了,例如西游记木偶奇遇
李克强出席全国大众创业万众创新活动周启动仪式丨来源新华社李克强出席全国大众创业万众创新活动周启动仪式强调持续推进大众创业万众创新聚众智汇众力发展市场主体壮大经济新动能9月15日,中共中央政治局常委国务院总理李克强在北京人民大