将数据库和项目结果搜索到 datagridview

Posted

技术标签:

【中文标题】将数据库和项目结果搜索到 datagridview【英文标题】:Search database and project results to datagridview 【发布时间】:2021-01-09 23:18:05 【问题描述】:

我有一个包含大约 100 个不同变量的 sql 数据库。我基本上想要的是能够根据一些变量逐一或多次搜索来搜索数据库。 为此,我在 VS 2010 中创建了一个搜索表单,其中包含所需数量的组合框(每个组合框代表一个变量并从数据库中获取不同的值)。 根据用户选择的变量,我希望结果显示在 datagridview 表上。

代码由于某种原因是错误的,我无法弄清楚。问题出在 da.Fill(datatable1) 出现意外错误。 是否有任何替代方案并提供一些指导来完成这个想法?

Private Sub display_datagrid()
    con2.ConnectionString = "Server= DESKTOP-KQG48T5\SQL2021; Database = Fotilas2021; Integrated Security = True;"
    con2.Open()

    
    Dim cmd2 As New SqlCommand("select Name,IdentityNumber,FatherSurname,LocalCelebDay,BirthNomos,NumofChilds,MilitaryService,CurrentCountry,CurrentCity,CellNumber,DateAdd,Occupation,OccupPosition,ElectWeight,ElectContact,ElectCategory,ElectCollege,DeleteGroup,ElectPeriphery,Sex,FatherName,MotherName,Birthday,FamilyStatus,BirthDimos,Adreess,CurrentNomos,Landline,OccupSpeciality,ElectImportance,ElectMechanism,ElectPeriphery,ElectDimotikiEnotita,ElectNumber,EduLanguages,SuggestSurname,SuggestPhone,ElectDimos,EduUniversity,Surname,FatherSurname,WifeName,NameDay,BirthCountry,BirthCity,HealthStatus,Postcode,CurrentDimos,HomeLine,Fax,OccupStatus,OccupFirm,ElectType,ElectCategory,ElectDiamerisma,EduLevel,EduPC,ElectEterodimotis,EduQualifications from Fotilas2021 where Name like '%" + ComboBox2.Text + "%', IdentityNumber like '%" + ComboBox3.Text + "%', FatherSurname like '%" + ComboBox4.Text + "%', LocalCelebDay like '%" + ComboBox5.Text + "%', BirthNomos like '%" + ComboBox6.Text + "%', NumofChilds like '%" + ComboBox7.Text + "%', MilitaryService like '%" + ComboBox8.Text + "%' CurrentCountry like '%" + ComboBox9.Text + "%', CurrentCity like '%" + ComboBox10.Text + "%', CellNumber like '%" + ComboBox11.Text + "%', DateAdd like '%" + ComboBox13.Text + "%', Occupation like '%" + ComboBox14.Text + "%', OccupPosition like '%" + ComboBox15.Text + "%', ElectWeight like '%" + ComboBox16.Text + "%', ElectContact like '%" + ComboBox17.Text + "%', ElectCategory like '%" + ComboBox19.Text + "%', ElectCollege like '%" + ComboBox20.Text + "%', DeleteGroup like '%" + ComboBox21.Text + "%', ElectPeriphery like '%" + ComboBox22.Text + "%', Sex like '%" + ComboBox30.Text + "%', FatherName like '%" + ComboBox31.Text + "%', MotherName like '%" + ComboBox32.Text + "%', Birthday like '%" + ComboBox33.Text + "%', FamilyStatus like '%" + ComboBox34.Text + "%', BirthDimos like '%" + ComboBox35.Text + "%', Adreess like '%" + ComboBox37.Text + "%', CurrentNomos like '%" + ComboBox38.Text + "%', Landline like '%" + ComboBox39.Text + "%', OccupSpeciality like '%" + ComboBox43.Text + "%', ElectImportance like '%" + ComboBox45.Text + "%', ElectMechanism like '%" + ComboBox50.Text + "%', ElectPeriphery like '%" + ComboBox51.Text + "%', ElectDimotikiEnotita like '%" + ComboBox52.Text + "%', ElectNumber like '%" + ComboBox53.Text + "%', EduLanguages like '%" + ComboBox56.Text + "%', SuggestSurname like '%" + ComboBox57.Text + "%', SuggestPhone like '%" + ComboBox29.Text + "%', ElectDimos like '%" + ComboBox23.Text + "%', EduUniversity like '%" + ComboBox27.Text + "%', Surname like '%" + ComboBox59.Text + "%', FatherSurname like '%" + ComboBox60.Text + "%', WifeName like '%" + ComboBox61.Text + "%', NameDay like '%" + ComboBox62.Text + "%', BirthCountry like '%" + ComboBox63.Text + "%', BirthCity like '%" + ComboBox64.Text + "%', HealthStatus like '%" + ComboBox65.Text + "%', Postcode like '%" + ComboBox66.Text + "%', CurrentDimos like '%" + ComboBox67.Text + "%', HomeLine like '%" + ComboBox68.Text + "%', Fax like '%" + ComboBox69.Text + "%', OccupStatus like '%" + ComboBox71.Text + "%', OccupFirm like '%" + ComboBox72.Text + "%', ElectType like '%" + ComboBox74.Text + "%', ElectCategory like '%" + ComboBox76.Text + "%', ElectDiamerisma like '%" + ComboBox81.Text + "%', EduLevel like '%" + ComboBox84.Text + "%', EduPC like '%" + ComboBox85.Text + "%', ElectEterodimotis like '%" + ComboBox25.Text + "%', EduQualifications like '%" + ComboBox28.Text + "%'", con1)

    Dim da As New SqlDataAdapter
    Dim datatable1 As New DataTable

    da.SelectCommand = command
    datatable1.Clear()
    da.Fill(datatable1)
    DtGrid_Search.DataSource = datatable1
    con2.Close()

End Sub

【问题讨论】:

IdentityNumber 的数据类型是什么?这是表的主键吗? 我相信您说您已经使用数据库中的不同值来填充组合框,那么为什么所有的 Like %...%?我假设某些字段是数字类型和日期类型?一个数字如何“喜欢”另一个数字?一个约会如何“喜欢”另一个约会?似乎所有这些都应该是 = (equals) 用户是否能够从无、某些、所有组合框中选择值?如果用户未从组合中进行选择,您将发送什么值? 您的选择列表中有一些重复的字段。 like 与通配符一起使用意味着搜索'day' 的用户将匹配'Monday''Dayton'、`'Doomsdayers',...正如玛丽建议的那样。这是他们期望从列表中选择一个值的结果吗?如果他们按两列搜索,他们会期待什么,例如必须 匹配 (AND) 还是匹配 (OR)?见SQL Injection。 SQL 数据库有 tables,由 rowscolumns 组成。您正在搜索的变量在哪里? 【参考方案1】:

你应该使用参数作为开始,你应该构造你的 SQL 以便每个参数都是可选的,例如

Dim sql = <sql>
              SELECT *
              FROM SomeTable
              WHERE (@Column1 IS NULL OR Column1 = @Column1)
              AND (@Column2 IS NULL OR Column2 = @Column2)
              AND (@Column3 IS NULL OR Column3 = @Column3)
          </sql>

这里有很多需要注意的地方。

首先,此代码使用 XML 文字。在(我认为)2015 年引入多行 String 文字之前,这是编写长内联 SQL 的最佳方式,因为它允许您将其拆分为多行而不会造成难以阅读的混乱。

其次,SQL 代码使用参数。如果你把 SQL 代码想象成一个 VB 方法,那么每个以@ 为前缀的东西基本上都是一个方法参数。执行 SQL 代码时,为每个参数提供一个值,就像调用 VB 方法时一样。参数使您的代码更易于阅读,不受格式问题的影响,最重要的是,不受 SQL 注入攻击。如果需要,您可以进行一些研究以了解更多信息。

最后,通过允许您将参数设置为NULL 以使其有效地被忽略,每个参数的使用方式使它们成为有效的可选。例如,如果您将@Column1 设置为NULL,那么WHERE 子句中的第一个标准对于每条记录都将为真,因此就像根本没有该标准一样。另一方面,如果您将@Columnn1 设置为一个值,那么第一个标准将仅适用于在Column1 中包含该值的记录。其他每个参数也是如此,因此您可以拥有任意数量的“可选”参数。

在您的 VB 代码中使用它的方法如下:

Dim table As New DataTable

Using adapter As New SqlDataAdapter(sql, "connection string here")
    With adapter.SelectCommand.Parameters
        .Add("@Column1", SqlDbType.VarChar, 50).Value = ComboBox1.Text
        .Add("@Column2", SqlDbType.VarChar, 50).Value = ComboBox2.Text
        .Add("@Column3", SqlDbType.VarChar, 50).Value = ComboBox3.Text
    End With

    adapter.Fill(table)
End Using

BindingSource1.DataSource = table
DataGridView1.DataSource = BindingSource1

显然细节可能会有所不同,但原则是固定的:使用 SQL 代码创建一个数据适配器,将适当的参数添加到SelectCommand,然后调用Fill 来填充您的DataTable。然后你可以做任何你想做的事情,例如通过BindingSource 将其绑定到DataGridView。添加参数时,只需指定与 SQL 代码中使用的名称相同的名称和适当的数据库数据类型,然后将 Value 设置为应用程序中的适当值,并根据需要转换或转换数据。

例如,如果您使用参数与数据库中的varchar(50) 列进行比较,则在添加参数时指定SqlDbType.VarChar50,并使用Value 设置@987654341 @。如果您的数据库列是 int 类型,那么您指定 SqlDbType.Int 并且没有大小,然后使用 Integer 设置 Value

如果你想忽略一个参数,那么正如我所说,你需要在 SQL 中将它设置为NULL。这在 VB 代码中可能如下所示:

.Add("@Column1", SqlDbType.VarChar, 50).Value = If(ComboBox1.SelectedItem Is Nothing, CObj(DBNull.Value), ComboBox1.Text)
.Add("@Column2", SqlDbType.VarChar, 50).Value = If(ComboBox2.SelectedItem Is Nothing, CObj(DBNull.Value), ComboBox2.Text)
.Add("@Column3", SqlDbType.VarChar, 50).Value = If(ComboBox3.SelectedItem Is Nothing, CObj(DBNull.Value), ComboBox3.Text)

在每种情况下,代码首先检查用户是否在适当的ComboBox 中选择了一个项目,如果没有,则将参数的Value 设置为DBNull.Value,这是一个ADO.NET 表示数据库NULL。如果选择了一个项目,则使用选定的值。您可以根据需要修改代码的细节,但原则是不变的。

请注意,CObj 是必需的,因为此处使用的 If 运算符要求两个可能的返回值是相同类型或一个可分配给另一个。 DBNullString 不是同一类型,也不继承另一个,因此您不能使用这两种类型。通过使用CObj 将一个类型转换为Object,您可以使另一个值成为任何类型,因为所有其他类型都继承Object

【讨论】:

以上是关于将数据库和项目结果搜索到 datagridview的主要内容,如果未能解决你的问题,请参考以下文章

如何读写DataGridView数据到Sql Table

DataGridView CellFormatting 事件阻止表单绘制

使用 C# 使用 CSV 文件填充 DataGridView,并使用结果更新 Access 数据库

通过 datagridview 搜索值

将数据从组合框获取到 datagridview

使用查询结果创建和绑定 DataGridViewColumn。将其添加到 DataGridView