从多个连接的字符串创建参数化 MySQL 查询
Creating a parameterised MySQL query from multiple concatenated strings
我打算做的是创建一些函数,这将帮助我创建大量 MySqlCommand
。但我错了(下面提供的信息)。
背景
我是通过在class中定义常量实现的,例如:
Public Const Create_Table = "CREATE TABLE IF NOT EXISTS `@arg0` (@arg1)"
诸如此类的字符串构成了我的参数化查询的基础。现在,这些参数不是单个值,它们实际上是串联的字符串。所以我知道我正在接近这里的危险水域,所以请耐心等待。
我使用以下函数连接参数:
Public Shared Function ListToQuery(values As List(Of String),
Optional ByVal separator As String = ", ") As String
Dim queryBuilder As New StringBuilder
For Each value As String In values
queryBuilder.Append((value) & separator)
Next
Dim query As String = queryBuilder.ToString
Return query.Remove(query.Length - 2)
End Function
一切正常;当我用列表调用它时:
Dim myValues As New List(Of String)
myValues.AddRange({"Int Primary", "Text Name"})
MsgBox(ListToQuery(myValues))
它 returns "Int Primary, Text Name"
- 完全正常。 然而,这就是事情开始出错的地方。
我的下一部分是基于几个参数创建 MySqlCommand,一个 String
数组。这是通过调用以下函数实现的:
Public Shared Function BuildCommand(args() As String, Command As String, connection As MySqlConnection) As MySqlCommand
Dim cmd As New MySqlCommand(Command, connection)
For i As Integer = 0 To args.Length - 1
'cmd.CommandText = cmd.CommandText.Replace("@arg" & i, args(i))
cmd.Parameters.AddWithValue("@arg" & i, MySqlHelper.EscapeString(args(i)))
Next
Return cmd
End Function
问题
我这样调用这个函数:
Dim myCommand as MySqlCommand = BuildCommand({"MyTableName", ListToQuery(myValues)}, Create_Table, myConnection)
Dim dr = myCommand.ExecuteReader()
似乎发生了什么,这是发生了错误,我发现了一些似乎在参数化查询中发生的事情:
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''Int Primary, Text Name')' at line 1
如果我正确解释此错误,则该参数似乎已封装在 '
中。现在请注意我的代码中 BuildCommand()
的注释。如果我要使用纯串联,该查询将 运行 就好了。
编辑:结果查询应该是:
CREATE TABLE IF NOT EXISTS `MyTableName` (Int Primary, Text Name)
问题
事实上,我有一对。首先,我想问一下这是否是一种安全的方式(即即使连接我的参数并在查询中使用参数)到 运行 一个命令,其次,我怎样才能避免出现这个错误?
我不太确定我是否可以在不导致查询变为 'unsafe' 或不修改一般 MySQL 语句的情况下单独解析每个参数。
我一直在与另一位用户讨论这个问题,他设法找到了这个问题:Parameterized dynamic sql query。这是在问一个类似的问题。但是,这与我遇到的问题不同。
提前致谢。
此函数生成一个 CREATE TABLE 命令。我多次遇到同样的问题,但直到现在我都没有找到合适的解决方案。相反,我自己创建查询:
Public Shared Function BuildCommand(args() As String, connection As MySqlConnection) As MySqlCommand
Dim sb As New StringBuilder
Dim cmd As New MySqlCommand
cmd.Connection = connection
sb.Append("CREATE TABLE IF NOT EXISTS`")
sb.Append(args(0))
sb.Append("`(")
For i As Integer = 1 To args.Length - 1
sb.Append("`")
sb.Append(args(i))
sb.Append("`,")
Next
sb.Remove(sb.Length - 1, 1)
sb.Append(")")
cmd.CommandText = sb.ToString
Return cmd
End Function
此代码与您之前给我看的代码不同,但现在我看到了您所做的更改以及您在什么情况下使用这些代码,事情就变得容易多了。
添加 SQL 参数时,您不需要转义它们的值,因为这是自动完成的。这可能就是为什么你会经历它被两次逃脱的原因。
变化:
cmd.Parameters.AddWithValue("@arg" & i, MySqlHelper.EscapeString(args(i)))
至:
cmd.Parameters.AddWithValue("@arg" & i, args(i))
...它应该可以工作(而且是安全的)!
我打算做的是创建一些函数,这将帮助我创建大量 MySqlCommand
。但我错了(下面提供的信息)。
背景
我是通过在class中定义常量实现的,例如:
Public Const Create_Table = "CREATE TABLE IF NOT EXISTS `@arg0` (@arg1)"
诸如此类的字符串构成了我的参数化查询的基础。现在,这些参数不是单个值,它们实际上是串联的字符串。所以我知道我正在接近这里的危险水域,所以请耐心等待。
我使用以下函数连接参数:
Public Shared Function ListToQuery(values As List(Of String),
Optional ByVal separator As String = ", ") As String
Dim queryBuilder As New StringBuilder
For Each value As String In values
queryBuilder.Append((value) & separator)
Next
Dim query As String = queryBuilder.ToString
Return query.Remove(query.Length - 2)
End Function
一切正常;当我用列表调用它时:
Dim myValues As New List(Of String)
myValues.AddRange({"Int Primary", "Text Name"})
MsgBox(ListToQuery(myValues))
它 returns "Int Primary, Text Name"
- 完全正常。 然而,这就是事情开始出错的地方。
我的下一部分是基于几个参数创建 MySqlCommand,一个 String
数组。这是通过调用以下函数实现的:
Public Shared Function BuildCommand(args() As String, Command As String, connection As MySqlConnection) As MySqlCommand
Dim cmd As New MySqlCommand(Command, connection)
For i As Integer = 0 To args.Length - 1
'cmd.CommandText = cmd.CommandText.Replace("@arg" & i, args(i))
cmd.Parameters.AddWithValue("@arg" & i, MySqlHelper.EscapeString(args(i)))
Next
Return cmd
End Function
问题
我这样调用这个函数:
Dim myCommand as MySqlCommand = BuildCommand({"MyTableName", ListToQuery(myValues)}, Create_Table, myConnection)
Dim dr = myCommand.ExecuteReader()
似乎发生了什么,这是发生了错误,我发现了一些似乎在参数化查询中发生的事情:
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''Int Primary, Text Name')' at line 1
如果我正确解释此错误,则该参数似乎已封装在 '
中。现在请注意我的代码中 BuildCommand()
的注释。如果我要使用纯串联,该查询将 运行 就好了。
编辑:结果查询应该是:
CREATE TABLE IF NOT EXISTS `MyTableName` (Int Primary, Text Name)
问题
事实上,我有一对。首先,我想问一下这是否是一种安全的方式(即即使连接我的参数并在查询中使用参数)到 运行 一个命令,其次,我怎样才能避免出现这个错误?
我不太确定我是否可以在不导致查询变为 'unsafe' 或不修改一般 MySQL 语句的情况下单独解析每个参数。
我一直在与另一位用户讨论这个问题,他设法找到了这个问题:Parameterized dynamic sql query。这是在问一个类似的问题。但是,这与我遇到的问题不同。
提前致谢。
此函数生成一个 CREATE TABLE 命令。我多次遇到同样的问题,但直到现在我都没有找到合适的解决方案。相反,我自己创建查询:
Public Shared Function BuildCommand(args() As String, connection As MySqlConnection) As MySqlCommand
Dim sb As New StringBuilder
Dim cmd As New MySqlCommand
cmd.Connection = connection
sb.Append("CREATE TABLE IF NOT EXISTS`")
sb.Append(args(0))
sb.Append("`(")
For i As Integer = 1 To args.Length - 1
sb.Append("`")
sb.Append(args(i))
sb.Append("`,")
Next
sb.Remove(sb.Length - 1, 1)
sb.Append(")")
cmd.CommandText = sb.ToString
Return cmd
End Function
此代码与您之前给我看的代码不同,但现在我看到了您所做的更改以及您在什么情况下使用这些代码,事情就变得容易多了。
添加 SQL 参数时,您不需要转义它们的值,因为这是自动完成的。这可能就是为什么你会经历它被两次逃脱的原因。
变化:
cmd.Parameters.AddWithValue("@arg" & i, MySqlHelper.EscapeString(args(i)))
至:
cmd.Parameters.AddWithValue("@arg" & i, args(i))
...它应该可以工作(而且是安全的)!