分享
 
 
 

从Linux上的DB2表中生成动态数据输入表单

王朝system·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

简介

在本文中,为了动态构建视图和表单,我将检查 ® DB2® Universal Database™ (UDB) 元数据。特别是,我将使用 Linux 上的 ® Kylix 3™ 和 Borland dbExpress 数据访问驱动程序,来分析 DB2 UDB 数据库表、字段(名称和类型),以允许用户选择特定的表、来回切换应该显示的字段,以及动态查看数据格和单独数据感知控件中的输出。

这是一种纯运行时方法;无需进行进一步编码。在后续文章中,我将使用 Borland Delphi™,通过动态生成表单,并在设计时将它们添加到项目中(用我们自己的数据库表单向导)来进一步介绍该方法。

从头开始

与前面介绍利用 Kylix 操作 DB2 的文章不同,在上一篇文章中,您已经在设计时使用 IDE 构建了整个应用程序,所以只需从连接 DB2 UDB 数据库开始即可。其他步骤都是在代码中完成的,都使用了从数据库自身中获得的元信息。

为了构建到 DB2 UDB SAMPLE 数据库的连接,需要使用 TSQLConnection 组件、开启新的 Kylix 3 项目,并将 TSQLConnection 组件放在表单上。可以右击 SQLConnection 组件来编辑连接属性。DriverName 应该是 DB2,Database 名称应该是 SAMPLE(或者其他任何数据库名 ―― 本文中的代码将处理所有现有 DB2 UDB 数据库)。还需要指定 User_Name 和 Password;此外,需要在运行时将它们输入登录对话框中。可以通过单击“check”按钮来测试连接属性的有效性,随后,可以看见以下截屏:

图 1. 成功连接的 DB2Connection

设计时的准备

一旦正确设置了 TSQLConnection 组件,就可以添加其他 dbExpress 组件,并将它们彼此相连,但是,不需要指定 SQL 语句或添加任何视图数据感知控件。在添加第一个附加组件时,在表单上放置一个 TSQLDataSet 组件,添加下一个组件时放置 TSQLConnection 组件。将 TSQLDataSet 的 SQLConnection 属性指向 TSQLConnection 组件。然后,在表单上放置一个 TDataSetProvider,并将其 DataSet 属性指向 TSQLDataSet 组件。

该组件后面是 TClientDataSet 组件,其 ProviderName 属性被设置为 TDataSetProvider 组件的名称。最后,删除表单上的 TDataSource 组件,并将其 DataSet 属性连接到 TClientDataSet 组件。这将为您提供 TSQLConnection - TSQLDataSet - TSQLDataSetProvider - TClientDataSet - TDataSource 的链接,在使用包含 DB2 UDB 数据库表的 Borland dbExpress 之前,您可以看到该链接。

这次,主要的不同在于您不能在 SQLDataSet 组件内部指定 SQL 语句。也不能在表单上放置任何可视数据感知组件,因为所有这些操作都将在运行时动态完成,并且都是基于 DB2 UDB 数据库中发现的元数据以及用户对表和字段的选择。

为了将元数据信息和从动态视图中生成的选项与一个数据窗格以及一个数据控件分离,需要用到 TPageControl 组件,如下方截屏中所示:

图 2. 设计时的动态表单

Meta Data TabSheet 由左边的 TListBox 控件和右边的 TCheckListBox 控件组成,前者将用 DB2 UDB SAMPLE 数据库表中的表名进行填充,后者将用已选定表中的有效字段名进行填充。

Generate 按钮将准备并执行 SQL 语句,将由此产生的数据放入一个窗格中(在 Data Grid 选项卡上),或者放入单独的数据感知控件中(在 Data Controls 选项卡中)。

检索 TableNames

首先要做的事情是检索数据库中的可用表名。假定 SQLConnection 组件可以建立到 DB2 UDB 数据库的连接(在本例中,是 SAMPLE 数据库或其他任何数据库),您只能显式打开连接,然后,您可以调用 GetTableNames 方法。该方法期望将 TStrings 变量作为第一个参数。而不是声明并使用我们自己的 TStringList 作为第一个参数,您可以直接将结果分配给 ListBox 的 Items 属性,如下面代码片段所示:

procedure TForm1.FormCreate(Sender: TObject);

begin

SQLConnection1.Connected := True;

SQLConnection1.GetTableNames(ListBox1.Items, False);

PageControl1.ActivePageIndex := 0

end;

在创建表单时(即,在 OnCreate 事件处理程序中),执行该代码的结果是:当启动应用程序时,用所有可用表填充 TListBox 控件。

分析字段定义

下一步取决于最终用户。为了选择特定的表,显示可用字段,最终用户必须双击 ListBox 控件中的表。这将激活一个事件处理程序,该程序采用 ListBox 中的表名,并为该表检索元数据。从元数据来看,您必须使用字段名的列表,将它们放置在第二个列表框 TCheckListBox 中。

为了做到这一点,您可以使用 TSQLDataSet 组件,将 CommandType 设置为 ctTable,并将 CommandText 设置为从第一个 TListBox 控件中选定的表的名称,该表可以在 ListBox1.Items[ListBox1.ItemIndex] 中找到。然后,一定不要激活(或者打开) TSQLDataSet,这一点很重要,因为它会将 select * 从您选定的表名发送到数据库,在此时,这项操作并不是您想要的。您应该调用 TSQLDataSet.FieldDefs.Update 方法,该方法只为字段定义检索元数据,没有为选定的表本身检索实际记录数据。

使用该字段定义元数据,您就可以遍历单独的字段定义,将字段的名称放置在 TCheckListBox 中(您还可以包括该字段的类型,但是,该类型您在下一步中才会用到,即,在为选定的字段创建适当的数据感知控件时才会用到)。

检索字段定义并更新 TCheckListBox 的源代码片段如下所示:

procedure TForm1.SelectTableClick(Sender: TObject);

var

i: Integer;

begin

ClientDataSet1.Active := False;

SQLDataSet1.CommandType := ctTable;

if ListBox1.ItemIndex = 0 then

SQLDataSet1.CommandText := ListBox1.Items[ListBox1.ItemIndex];

SQLDataSet1.FieldDefs.Update; // get meta information

CheckListBox1.Clear;

for i:=0 to Pred(SQLDataSet1.FieldDefs.Count) do

CheckListBox1.Items.Add(SQLDataSet1.FieldDefs[i].Name)

end;

注意,在添加新的字段名之前,应该清除 TCheckListBox,这样,最终用户就可以连续双击不同的表名,查看每次出现在 TCheckListBox 表中的新的字段列表。

以下截屏显示了第一次双击位于表单左边 TListBox 中的 EMPLOYEE 表的效果,然后,可以检查复选框,获得位于表单右边的 TCheckListBox 表中的前 11 个字段。

图 3. 元数据:表和字段

下一步是生成 SQL 语句,只选择指定表(本例中是 EMPLOYEE)中复选的字段,然后在数据格以及数据感知控件中显示结果。

生成动态 SQL 语句

通过将 TSQLDataSet 的 CommandType 属性设置为 ctQuery,可以启动 Generate 按钮(图 3 中可以看见它)的 OnClick 事件处理程序。这时,不需要在 CommandText 中指定 TableName,但实际的 SQL 语句会从指定的表中选择复选的字段。您可以从把 SELECT 分配给 CommandText 属性开始,然后遍历 TCheckListBox 控件中的项。注意,您无需再次从选定的表中检索元数据,因为相应的字段名已经添加到 TCheckListBox 中,因此,您可以只使用该控件中的字段名(只需验证其复选属性是否被设为 True,以便使用每个单独的字段名)。

下方代码片段中的变量 comma 是必需的,除了首字段之外,要确保每个字段前面都插入了一个逗号。这将在选定字段列表中产生一个包含一个或多个字段的有效 SQL 语句 。

procedure TForm1.btnGenerateClick(Sender: TObject);

var

i,Y: Integer;

comma: Boolean;

begin

ClientDataSet1.Active := False;

SQLDataSet1.CommandType := ctQuery;

SQLDataSet1.CommandText := 'SELECT ';

comma := False;

for i:=0 to Pred(CheckListBox1.Items.Count) do

begin

if CheckListBox1.Checked[i] then

begin

if not comma then comma := True

else

SQLDataSet1.CommandText := SQLDataSet1.CommandText + ', ';

SQLDataSet1.CommandText := SQLDataSet1.CommandText + CheckListBox1.Items[i]

end

end;

if ListBox1.ItemIndex = 0 then

SQLDataSet1.CommandText :=

SQLDataSet1.CommandText + ' FROM ' + ListBox1.Items[ListBox1.ItemIndex];

//ShowMessage(SQLDataSet1.CommandText);

ClientDataSet1.Active := True;

PageControl1.ActivePageIndex := PageControl1.ActivePageIndex + 1

end;

在完成对字段列表的操作之后,您惟一需要做的就是添加 FROM 字符串,该字符串后面是数据库表的名称,您仍然可以在 TListBox 控件中找到该表。在完成这一步骤之后,您可以将 TClientDataSet 组件的 Active 属性设置为 True,这将激活 TSQLDataSet 组件中的 SQL 命令,使数据有效。

作为示例,PageControl 的第二个页面可以包含附带指向 TDataSource 组件的 DataSource 属性的 TDBGrid 控件,如下方截屏所示:

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有