参数化 SQL 查询
Parameterize SQL Queries
我想参数化一些 SQL 语句,这样我的代码就不会再受到 SQL 注入的影响但是我实际上没有计划如何参数化例如 where 子句。
Dim accID As String = DatabaseConnecter.readField("SELECT ID FROM accounts WHERE accountname ='" & user & "' AND password='" & pw & "';")
问题是如果您输入给定的用户名,例如测试和扩展用户名。您无需在应用程序中输入密码即可登录。
编辑:
Public Function readField(ByVal sql As String) As String
Dim output As String = "ERROR"
Using cn = New MySqlConnection(connString.ToString())
Using cmd = New MySqlCommand(sql, cn)
cn.Open()
Using rd = cmd.ExecuteReader()
Try
rd.Read()
output = rd.GetString(0)
rd.Close()
Catch ex As Exception
End Try
End Using
cn.Close()
End Using
End Using
Return output
End Function
´´´
Private Function GetID(User As String, pw As String) As String
Using cmd As New SqlCommand("SELECT ID FROM accounts WHERE accountname =@user AND password=@password", New SqlConnection(SQLConnString))
cmd.Parameters.AddWithValue("@user", User)
cmd.Parameters.Add("@password", SqlDbType.NVarChar)
cmd.Parameters("@password").Value = pw
Try
cmd.Connection.Open()
Return cmd.ExecuteScalar()
Catch ex As Exception
'handle error
Return Nothing
Finally
cmd.Connection.Close()
End Try
End Using
End Function
我已经演示了两种设置参数的方法。搜索更多信息或比较。
要进行参数化查询,您需要创建参数并编写适当的 SQL 文本,在其中代替用户直接键入的值,您有参数占位符。
因此,例如,您 sql 文本应该是这样的
Dim sqlText = "SELECT ID FROM accounts WHERE accountname =@name AND password=@pwd"
现在您有了一个参数化文本,但我们仍然需要创建将与您的 sql 命令一起发送到数据库引擎的参数。
您可以在调用执行查询的方法之前通过这种方式创建参数(在本例中为两个)
Dim p1 as MySqlParameter = new MySqlParameter("@name", MySqlDbType.VarChar)
p1.Value = user
Dim p2 as MySqlParameter = new MySqlParameter("@pwd", MySqlDbType.VarChar)
p2.Value = password
Dim pms As List(Of MySqlParameter) = new List(Of MySqlParameter)()
pms.Add(p1)
pms.Add(p2)
现在我们需要将此列表传递给您的方法(这需要更改您的方法签名)
DatabaseConnecter.readField(sqlText, pms)
方法本身应该更改为
Public Function readField(ByVal sql As String, Optional pms As List(Of MySqlParameter) = Nothing) As String
Dim output As String = "ERROR"
Using cn = New MySqlConnection(connString.ToString())
Using cmd = New MySqlCommand(sql, cn)
cn.Open()
' This block adds the parameter defined by the caller to the command
' The parameters are optional so we need to check if we have really received the list or not
if pms IsNot Nothing Then
cmd.Parameters.AddRange(pms.ToArray())
End If
Using rd = cmd.ExecuteReader()
Try
rd.Read()
output = rd.GetString(0)
rd.Close()
Catch ex As Exception
End Try
End Using
' no need to close when inside a using block
' cn.Close()
End Using
End Using
Return output
End Function
该方法现在有一个可选参数,它将包含查询所需的参数列表(如果您的查询不需要参数,则不包含任何参数)。该列表被添加到命令参数集合中,现在执行查询。
最后注意:以明文形式将密码存储到数据库中是一个众所周知的安全问题。我建议您搜索 how to store passwords in a database.
我想参数化一些 SQL 语句,这样我的代码就不会再受到 SQL 注入的影响但是我实际上没有计划如何参数化例如 where 子句。
Dim accID As String = DatabaseConnecter.readField("SELECT ID FROM accounts WHERE accountname ='" & user & "' AND password='" & pw & "';")
问题是如果您输入给定的用户名,例如测试和扩展用户名。您无需在应用程序中输入密码即可登录。
编辑:
Public Function readField(ByVal sql As String) As String
Dim output As String = "ERROR"
Using cn = New MySqlConnection(connString.ToString())
Using cmd = New MySqlCommand(sql, cn)
cn.Open()
Using rd = cmd.ExecuteReader()
Try
rd.Read()
output = rd.GetString(0)
rd.Close()
Catch ex As Exception
End Try
End Using
cn.Close()
End Using
End Using
Return output
End Function
´´´
Private Function GetID(User As String, pw As String) As String
Using cmd As New SqlCommand("SELECT ID FROM accounts WHERE accountname =@user AND password=@password", New SqlConnection(SQLConnString))
cmd.Parameters.AddWithValue("@user", User)
cmd.Parameters.Add("@password", SqlDbType.NVarChar)
cmd.Parameters("@password").Value = pw
Try
cmd.Connection.Open()
Return cmd.ExecuteScalar()
Catch ex As Exception
'handle error
Return Nothing
Finally
cmd.Connection.Close()
End Try
End Using
End Function
我已经演示了两种设置参数的方法。搜索更多信息或比较。
要进行参数化查询,您需要创建参数并编写适当的 SQL 文本,在其中代替用户直接键入的值,您有参数占位符。
因此,例如,您 sql 文本应该是这样的
Dim sqlText = "SELECT ID FROM accounts WHERE accountname =@name AND password=@pwd"
现在您有了一个参数化文本,但我们仍然需要创建将与您的 sql 命令一起发送到数据库引擎的参数。
您可以在调用执行查询的方法之前通过这种方式创建参数(在本例中为两个)
Dim p1 as MySqlParameter = new MySqlParameter("@name", MySqlDbType.VarChar)
p1.Value = user
Dim p2 as MySqlParameter = new MySqlParameter("@pwd", MySqlDbType.VarChar)
p2.Value = password
Dim pms As List(Of MySqlParameter) = new List(Of MySqlParameter)()
pms.Add(p1)
pms.Add(p2)
现在我们需要将此列表传递给您的方法(这需要更改您的方法签名)
DatabaseConnecter.readField(sqlText, pms)
方法本身应该更改为
Public Function readField(ByVal sql As String, Optional pms As List(Of MySqlParameter) = Nothing) As String
Dim output As String = "ERROR"
Using cn = New MySqlConnection(connString.ToString())
Using cmd = New MySqlCommand(sql, cn)
cn.Open()
' This block adds the parameter defined by the caller to the command
' The parameters are optional so we need to check if we have really received the list or not
if pms IsNot Nothing Then
cmd.Parameters.AddRange(pms.ToArray())
End If
Using rd = cmd.ExecuteReader()
Try
rd.Read()
output = rd.GetString(0)
rd.Close()
Catch ex As Exception
End Try
End Using
' no need to close when inside a using block
' cn.Close()
End Using
End Using
Return output
End Function
该方法现在有一个可选参数,它将包含查询所需的参数列表(如果您的查询不需要参数,则不包含任何参数)。该列表被添加到命令参数集合中,现在执行查询。
最后注意:以明文形式将密码存储到数据库中是一个众所周知的安全问题。我建议您搜索 how to store passwords in a database.