如何从 Delphi 中的 SQL 服务器数据库服务器填充组合框?
How can I populate a combobox from a SQL Server database server in Delphi?
首先,我是 Delphi 的新手,我检查了这里的所有相关主题,但似乎没有任何效果。
我只是想用 SQL 服务器数据库中的列值填充 TComboBox
。
所以基本上,我有一个 VCL 表单和一个 DataModule
,其中包含一个 ADOConnection
和一个 ADOQuery
。 ADOConnection
连接到我的数据库(测试连接表明它成功)并且 ADOQuery
连接到我的 ADOConnection
。 VCL 窗体和 DataModules
是“连接”的。
(实际上还有另一个问题:每当我尝试在我的 ADOQuery
的属性中输入 SELECT name FROM Partners;
并尝试将其设置为活动时,它一直说“无效的对象名称 'Partners'"。SQL 语句是正确的,我在 SSMS 中对其进行了测试,它检索数据没有任何错误。但我不确定这是否是这里的主要问题。
基本上,这是我的代码:
procedure TFormInsertNewItem.ComboBoxPartnersDropDown(Sender: TObject);
begin
with DataModule1 do
begin
ComboBoxPartners.Items.Clear;
ADOQueryFillPartners.SQL.Clear;
ADOQueryFillPartners.SQL.Add('SELECT name FROM Partners;');
ADOQueryFillPartners.Active:=true;
ADOQueryFillPartners.Open;
while not ADOQueryFillPartners.Eof do begin
ComboBoxPartners.Items.Add(ADOQueryFillPartners.FieldByName('name').AsString);
ADOQueryFillPartners.Next;
end;
ADOQueryFillPartners.Active:=false;
ADOQueryFillPartners.Free;
end;
end;
每当我点击下拉它时(或者如果在加载表单时运行它可能会更好,但我不知道如何才能准确地引用该事件),它应该填满它。好吧,它不会。我尝试使用 TDBComboBox
和 TDBLookUpComboBox
,设置它们的数据源,但它只向组合框添加了 1 个项目。
任何人都可以帮助我解决我搞砸的问题以及如何让它工作吗?
您发布的代码中存在多个问题。
显然,您要做的第一件事就是正确打开您的查询。如果您无法通过 运行 查询来获取数据,则无法使用该数据来填充组合框。在数据模块上测试 ADOConnection,看看是否可以通过将其 Connected
属性 设置为 True
.
来连接到数据库
如果这不起作用,那么您需要正确设置 ConnectionString
。 (确保将 Connected
属性 设置回 False
。您应该在数据模块的 OnCreate
事件中连接,并在数据模块的 OnDestroy
事件中断开连接。 )
如果确实有效,请检查以确保将 ADOQuery 的 Connection
属性 设置为指向您的 ADOConnection,然后使用 ADOQuery.SQL
属性 输入你的 SQL 声明。完成后,将 ADOQuery.Active
属性 设置为 True
。 (同样,不要忘记将其设置回 False
并在 运行 时在您的代码中打开它。)
接下来,您使用了错误的事件。您应该在表单的 OnCreate
事件中执行此操作。
此外,查询不需要同时使用 Active
和 Open
。他们做同样的事情;它们之间的唯一区别是 Active
是一个可以测试的布尔值 属性 (if Query1.Active then
) 而 Open
只是一个方法。没有理由打开已经激活的查询或激活已经打开的查询。
此外,您在方法末尾释放了查询,这意味着下次调用组合框 OnDropDown
事件时,您将访问无效的 class 实例,这将导致访问冲突。
最后,您应该在清除和填充组合框之前调用 BeginUpdate
,然后在完成后调用 EndUpdate
。
更正确的代码版本应该是这样的
procedure TFormInsertNewItem.FormCreate(Sender: TObject);
begin
with DataModule1 do
begin
{
I'm not sure why you're doing this at all. If you set the ADOQuery.SQL property
at designtime, and it never changes, you can remove the next two lines.
}
ADOQueryFillPartners.SQL.Clear;
ADOQueryFillPartners.SQL.Add('SELECT name FROM Partners;');
ADOQueryFillPartners.Active:=true;
try
ComboBoxPartners.Items.BeginUpdate;
while not ADOQueryFillPartners.Eof do begin
ComboBoxPartners.Items.Add(ADOQueryFillPartners.FieldByName('name').AsString);
ADOQueryFillPartners.Next;
end;
finally
ComboBoxPartners.Items.EndUpdate;
end;
ADOQueryFillPartners.Active:=false;
end;
end;
首先,我是 Delphi 的新手,我检查了这里的所有相关主题,但似乎没有任何效果。
我只是想用 SQL 服务器数据库中的列值填充 TComboBox
。
所以基本上,我有一个 VCL 表单和一个 DataModule
,其中包含一个 ADOConnection
和一个 ADOQuery
。 ADOConnection
连接到我的数据库(测试连接表明它成功)并且 ADOQuery
连接到我的 ADOConnection
。 VCL 窗体和 DataModules
是“连接”的。
(实际上还有另一个问题:每当我尝试在我的 ADOQuery
的属性中输入 SELECT name FROM Partners;
并尝试将其设置为活动时,它一直说“无效的对象名称 'Partners'"。SQL 语句是正确的,我在 SSMS 中对其进行了测试,它检索数据没有任何错误。但我不确定这是否是这里的主要问题。
基本上,这是我的代码:
procedure TFormInsertNewItem.ComboBoxPartnersDropDown(Sender: TObject);
begin
with DataModule1 do
begin
ComboBoxPartners.Items.Clear;
ADOQueryFillPartners.SQL.Clear;
ADOQueryFillPartners.SQL.Add('SELECT name FROM Partners;');
ADOQueryFillPartners.Active:=true;
ADOQueryFillPartners.Open;
while not ADOQueryFillPartners.Eof do begin
ComboBoxPartners.Items.Add(ADOQueryFillPartners.FieldByName('name').AsString);
ADOQueryFillPartners.Next;
end;
ADOQueryFillPartners.Active:=false;
ADOQueryFillPartners.Free;
end;
end;
每当我点击下拉它时(或者如果在加载表单时运行它可能会更好,但我不知道如何才能准确地引用该事件),它应该填满它。好吧,它不会。我尝试使用 TDBComboBox
和 TDBLookUpComboBox
,设置它们的数据源,但它只向组合框添加了 1 个项目。
任何人都可以帮助我解决我搞砸的问题以及如何让它工作吗?
您发布的代码中存在多个问题。
显然,您要做的第一件事就是正确打开您的查询。如果您无法通过 运行 查询来获取数据,则无法使用该数据来填充组合框。在数据模块上测试 ADOConnection,看看是否可以通过将其 Connected
属性 设置为 True
.
如果这不起作用,那么您需要正确设置 ConnectionString
。 (确保将 Connected
属性 设置回 False
。您应该在数据模块的 OnCreate
事件中连接,并在数据模块的 OnDestroy
事件中断开连接。 )
如果确实有效,请检查以确保将 ADOQuery 的 Connection
属性 设置为指向您的 ADOConnection,然后使用 ADOQuery.SQL
属性 输入你的 SQL 声明。完成后,将 ADOQuery.Active
属性 设置为 True
。 (同样,不要忘记将其设置回 False
并在 运行 时在您的代码中打开它。)
接下来,您使用了错误的事件。您应该在表单的 OnCreate
事件中执行此操作。
此外,查询不需要同时使用 Active
和 Open
。他们做同样的事情;它们之间的唯一区别是 Active
是一个可以测试的布尔值 属性 (if Query1.Active then
) 而 Open
只是一个方法。没有理由打开已经激活的查询或激活已经打开的查询。
此外,您在方法末尾释放了查询,这意味着下次调用组合框 OnDropDown
事件时,您将访问无效的 class 实例,这将导致访问冲突。
最后,您应该在清除和填充组合框之前调用 BeginUpdate
,然后在完成后调用 EndUpdate
。
更正确的代码版本应该是这样的
procedure TFormInsertNewItem.FormCreate(Sender: TObject);
begin
with DataModule1 do
begin
{
I'm not sure why you're doing this at all. If you set the ADOQuery.SQL property
at designtime, and it never changes, you can remove the next two lines.
}
ADOQueryFillPartners.SQL.Clear;
ADOQueryFillPartners.SQL.Add('SELECT name FROM Partners;');
ADOQueryFillPartners.Active:=true;
try
ComboBoxPartners.Items.BeginUpdate;
while not ADOQueryFillPartners.Eof do begin
ComboBoxPartners.Items.Add(ADOQueryFillPartners.FieldByName('name').AsString);
ADOQueryFillPartners.Next;
end;
finally
ComboBoxPartners.Items.EndUpdate;
end;
ADOQueryFillPartners.Active:=false;
end;
end;