【问题标题】:How to create MySqlCommand object without know the number of parameter?如何在不知道参数个数的情况下创建 MySqlCommand 对象?
【发布时间】:2016-01-11 16:56:33
【问题描述】:

我正在尝试创建 MySQLCommand 对象以对数据库表执行查询。现在我的问题是:

所有记录都存储在这个DataRow列表中:Records,这个列表包含不同表的记录字段。通常为了在表中添加结果,我定义了一个MySqlCommand 对象,稍后使用参数化查询传递参数,但是,在这种情况下,我不知道参数的数量,我只有一个包含很多记录的列表里面。现在存储此记录的表的名称包含在列表的第一个索引中,所以当我迭代列表时,只需跳过第一个索引并获取所有值。谁能告诉我这是怎么做到的?

示例:

Dim query = "INSERT INTO table (name, description) VALUES (@namep, @descriptionp)"
MyCommand = New MySqlCommand(query, my connection here)
MyCommand.Parameters.AddWithValue("@namep", "some value")+
MyCommand.Parameters.AddWithValue("@descriptionp", "another value")

这是我平时做的MySqlCommand,现在想象一下,在我的列表中有很多记录,如namedescription,还有其他查询的参数。如何创建类似的结构来添加此参数?

【问题讨论】:

  • 我想自己添加参数是很容易的部分。但是为实际查询构建字符串需要一些逻辑。您是否拥有构建它所需的所有信息?显示您尝试构建的实际 SQL 查询的示例。对于实际查询中的任何“未知”元素,你会从哪里得到它的值? (表名、列名等)
  • 我已经添加了一个例子
  • 该查询的哪些组件是“未知的”?大概你在某处有一个表名作为字符串,以及列名和值的集合?您可以使用这些组件为查询构建字符串,主要是通过循环该键/值集合。 (循环中的一个简单递增值可以用作参数名称。)您将用于构建查询的信息是什么?
  • 嗯,递增索引是一个好主意,但正如我所说,我不知道查询结构,因为这个 DataRow 中有很多价值,所以创建递增索引该参数只是部分解决方案。

标签: vb.net


【解决方案1】:

(我的VB很生锈,请耐心等待......)

大概你有几个值。特别是表名和表示列名和列值的键/值对的集合。使用这些,您可以为查询动态构建字符串。

从查询的基本结构开始。像这样的:

Dim query As New StringBuilder()
query.Append("INSERT INTO ")
' TODO: append table name
query.Append(" (")
' TODO: append column names (loop)
query.Append(") VALUES (")
' TODO: append parameter names (loop)
query.Append(")")
Dim MyCommand As New MySqlCommand(query.ToString(), someConnection)
' TODO: append actual parameters (loop)

让我们一次一个地浏览每个TODO 组件...

1. 表名是简单的部分,因为不涉及循环。假设它在一个变量中:

query.Append(someTableName)

2. 您可以调整各种循环的性能,但为了简单起见,现在让我们将键/值对循环 3 次。 (我们实际上将使用内部有循环的内置方法,但重点仍然存在。)对于列名,假设您有一个字符串数组:

query.Append(string.Join(",", someColumnNamesArray))

(注意:使用string.Join() 而不是手动循环的原因是为了避免必须为是否在第一个/最后一个条目中包含"," 分隔符做一些潜在的丑陋逻辑。)

3. 对于参数名称,只需使用数字即可。我不知道是否允许参数以数字开头,所以为了安全起见,让我们任意让它们以"a" 开头,然后是数字。您可以使用Enumerable.Range() 获取数组长度的整数列表。所以是这样的:

query.Append(string.Join(",", Enumerable.Range(0, someColumnNamesArray.Count()).Select(Function(x) string.Format("@a{0}", x))))

我承认,这是一段看起来很复杂的代码。但它的基本作用是:

  • 创建一个从 0 到列名数组长度的整数范围。
  • 根据这些整数选择一个格式化字符串,创建一个字符串列表,如"@a0""@a1" 等。
  • 使用string.Join() 将该列表转换为一个以逗号分隔的字符串。

如果它看起来更干净,请随意在多行上执行此操作。

此时您应该有您的查询。像这样的:

"INSERT INTO someTable (someColumn, anotherColumn, andAnother) VALUES (@a0, @a1, @a2)"

4.然后你可以循环你的值数组来添加你的参数:

For i As Integer = 1 To someValuesArray.Count()
    MyCommand.Parameters.AddWithValue(string.Format("@a{0}", i), someValuesArray[i])
Next

【讨论】:

  • 表名没问题,但我如何识别正确的查询?让我更好地解释一下,我如何创建一个查询,该查询具有表 x 对表 y 的结构语句等等?怎么说呢,这个列表中有很多不同表的记录,所以此时的问题是查询,因为我不知道它的结构。我不知道我是否清楚,例如:表1,要插入的记录(名称和描述),表2,要插入的记录(值,持续时间,服务)。那么如何创建差异字符串查询呢?我是否应该将查询连同表的名称一起传递?
  • @Sandokan:嗯,在某些时候,您需要有足够的信息来逻辑地为任何给定表构建INSERT 查询。如果您拥有的只是一堆列并且无法确定它们属于哪些表,那么您没有足够的信息来构建查询。
  • 这个 string.Format("@a{0}", x)) 包含“x”变量,但我没有看到任何价值,你能解释一下吗?
  • @Sandokan:x 是在 LINQ 中迭代集合时使用的变量。在线查看一些 LINQ 扩展方法的 VB 示例。
猜你喜欢
  • 1970-01-01
  • 2018-05-05
  • 2019-06-13
  • 1970-01-01
  • 2023-03-10
  • 2020-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多