VB.NET学习笔记:ADO.NET操作ACCESS数据库——执行含参数SQL语句或存储过程,防止SQL注入攻击

习惯上,我喜欢直接把SQL语句通过连接拼写出来。
为测试,我们新建一Windos应用程序项目,在窗体中拉入一个DataGridView、2个TextBox(TxtID和TxtGrade)、2 个Label和一个Button控件。设计界面如图:
在这里插入图片描述
数据库里的表数据如图:
在这里插入图片描述

一、拼接SQL语句进行数据库查询

测试代码:连接拼写SQL语句

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        '连接数据库
        Dim conn As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=F:\test.accdb;")
        '打开数据库
        conn.Open()
        '生成命令
        Dim cmd As New OleDbCommand()
        cmd.CommandType = CommandType.Text
        cmd.Connection = conn

        cmd.CommandText = "SELECT gradeID, grade FROM gradetbl" _
                        & " WHERE gradeID=" & TxtID.Text & " AND grade='" & TxtGrade.Text & "';"

        '执行命令
        Dim adapter As New OleDbDataAdapter()
        adapter.SelectCommand = cmd
        '填充DataTable
        Dim dt As New DataTable
        adapter.Fill(dt)
        DataGridView1.DataSource = dt

        '关闭数据库
        conn.Close()
    End Sub

测试1:查询ID为1,年级为“一年级”的数据,如图:
在这里插入图片描述
测试结果:
在这里插入图片描述
拼接得到的SQL语句:SELECT gradeID, grade FROM gradetbl WHERE gradeID=1 AND grade='一年级';,如图:
在这里插入图片描述
测试2:恶意输入,如:ID输入“6 or 1=1”,年级输入“0’ or ‘1’='1 ”,如图
在这里插入图片描述
测试结果:查询得到表中全部数据,这会把数据暴露给恶意使用者,也称为SQL注入攻击,如图在这里插入图片描述
拼接得到的SQL语句:SELECT gradeID, grade FROM gradetbl WHERE gradeID=6 or 1=1 AND grade='0' or '1'='1 ';,如图
在这里插入图片描述

二、执行含参数SQL语句

测试代码:含参数SQL语句

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        '连接数据库
        Dim conn As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=F:\test.accdb;")
        '打开数据库
        conn.Open()
        '生成命令
        Dim cmd As New OleDbCommand()
        cmd.CommandType = CommandType.Text
        cmd.Connection = conn

       cmd.CommandText = "SELECT gradeID, grade FROM gradetbl WHERE gradeID=? AND grade=?;"
       cmd.Parameters.Add("@gradeID", OleDbType.BigInt).Value = TxtID.Text
       cmd.Parameters.Add("@grade", OleDbType.VarChar).Value = TxtGrade.Text

        '执行命令
        Dim adapter As New OleDbDataAdapter()
        adapter.SelectCommand = cmd
        '填充DataTable
        Dim dt As New DataTable
        adapter.Fill(dt)
        DataGridView1.DataSource = dt

        '关闭数据库
        conn.Close()
    End Sub

我们也进行“拼接SQL语句进行数据库查询”的2个测试。
测试1结果:如图
在这里插入图片描述
测试2结果:报错——System.FormatException:“将参数值从 String 转换到 Int64 失败。” FormatException: 输入字符串的格式不正确。如图:
在这里插入图片描述
原来,当命令对象使用参数来将值传递给 SQL 语句或存储过程。 与命令文本不同,参数输入被视为文本值,而不是可执行代码。 这样可帮助抵御“SQL 注入”攻击,防止攻击者将命令插入 SQL 语句而危及数据库的安全。
代码关键解释:

1、占位符(?)

需要执行的SQL语句:

cmd.CommandText = "SELECT gradeID, grade FROM gradetbl" _
                        & " WHERE gradeID=" & TxtID.Text & " AND grade='" & TxtGrade.Text & "';"

在书写SQL语句时用(而且是必须用)占位符?代替了具体的值。如:

cmd.CommandText = "SELECT gradeID, grade FROM gradetbl WHERE gradeID=? AND grade=?;"

其实参数占位符的语法取决于数据源。 .NET Framework 数据提供程序处理命名和指定参数和参数占位符的方式各不相同。对于SQLServer.net数据提供程序是以 “@参数名”格式使用命名参数。而OLEDB.NET 访问接口不支持命名的参数,必须使用问号 (?) 占位符。

2、为命令提供参数

使用Add方法为OleDbCommand对象的Parameters属性添加OleDbParameter对象。
其实是通过OleDbCommand对象的Parameters属性获取 OleDbParameterCollection对象,而OleDbParameterCollection对象表示SQL 语句或存储过程的参数(即OleDbParameter对象)的集合。
常用的Add方法如下:
OleDbParameterCollection对象的Add方法

(1)、第1、2个重载了的Add方法

必须先实例化OleDbParameter对象,OleDbParameter对象常用的构造函数如下:
OleDbParameter对象常用的构造函数
通过OleDbParameter对象构造函数初始化OleDbParameter对象必要的属性,如至少需要设置OleDbParameter对象的名称ParameterName属性、值Value属性2个属性。
无参数构造函数示例代码:

Dim parameter As New OleDbParameter()
        parameter.ParameterName = "@ID" '一个你喜欢的名称,当然最好是字段名
        parameter.OleDbType = OleDbType.BigInt '参数的数据类型,默认值为 VarWChar
        parameter.Size = 5 '列中的数据的最大大小(以字节为单位)。 默认值将根据参数值进行推断。
        parameter.Direction = ParameterDirection.Input 'ACCESS中只能输入参数,而默认值为 Input,所以此属性不必设置
        parameter.Value = TxtID.Text '获取或设置参数的值,默认值为 null。

当然也可以将以上参数传入构造函数里,如:

Dim parameter As New OleDbParameter("@ID", dataType:=OleDbType.BigInt)
        parameter.Size = 5
        parameter.Value = TxtID.Text

或:

Dim parameter As New OleDbParameter("@ID",TxtID.Text)
        parameter.Size = 5
        parameter.OleDbType = OleDbType.BigInt

或:

Dim parameter As New OleDbParameter("@cityer", OleDbType.BigInt, 5)
        parameter.Value =TxtID.Text

以上不同的构造函数得到的效果是一样的。
实例化OleDbParameter对象后,就可以用Add方法为OleDbCommand对象的Parameters属性添加参数了。

cmd.Parameters.Add(parameter)

集合中的参数数量必须等于的命令文本中的参数占位符的个数,否则适用于 OLE DB.NET Framework 数据提供程序可能会引发错误。本示例代码的SQL语句中还有一个参数占位符,所以还需按以上方法再添加一个参数:

Dim parameter1 As New OleDbParameter()
        parameter1.ParameterName = "@grade"
        parameter1.OleDbType = OleDbType.VarChar
        parameter1.Size = 10
        parameter1.Direction = ParameterDirection.Input
        parameter1.Value = TxtGrade.Text
        cmd.Parameters.Add(parameter1)

这里要特别注意这两句代码的先后顺序一定不能颠倒:

cmd.Parameters.Add(parameter)
cmd.Parameters.Add(parameter1)

OLEDB.NET 访问接口不支持命名的参数,因此,在把OleDbParameter对象添加到OleDbParameterCollection中的顺序必须直接对应于参数占位符(?)所在的命令文本中的位置。

(2)、其他Add方法

向Add方法中传入的参数不是一个OleDbParameter对象,而是OleDbParameter所必须的属性值,在Add方法内部构建OleDbParameter对象,因此省去了实例化OleDbParameter对象的步骤。
如:

cmd.Parameters.Add("@ID", OleDbType.BigInt).Value =TxtID.Text
cmd.Parameters.Add("@grade", OleDbType.VarChar).Value = TxtGrade.Text

或:

cmd.Parameters.Add("@ID", OleDbType.BigInt, 5).Value =TxtID.Text
cmd.Parameters.Add("@grade", OleDbType.VarChar, 10).Value =TxtGrade.Text

特别注意添加的顺序不能颠倒。
下面这个方法已过时,不宜采用:

cmd.Parameters.Add("@ID", TxtID.Text)

三、执行ACCESS“存储过程”

ACCESS中的“存储过程”无法与SQL Server相比。ACCESS不支持多条SQL语句、不支持逻辑语句、不支持输出参数等等,说白了,所谓的ACCESS“存储过程”就是一个“查询”对象。
首先,需要在ACCESS应用程序中创建查询对象(可含参数或不含参数)。如图:
创建ACCESS“存储过程”
执行无参数“存储过程”的代码:

'连接数据库
        Dim conn As New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=F:\position.mdb;Jet OLEDB:Database Password=#")
        '打开数据库
        conn.Open()
        '生成命令
        Dim cmd As New OleDbCommand()
        cmd.CommandType = CommandType.StoredProcedure '设置使用存储过程
        cmd.Connection = conn
        cmd.CommandText = "StoredProcedureNoParameters" '存储过(查询对象)的名称
        '执行命令
        Dim adapter As New OleDbDataAdapter()
        adapter.SelectCommand = cmd
        '填充DataTable
        Dim dt As New DataTable
        adapter.Fill(dt)
        DataGridView1.DataSource = dt
        '关闭数据库
        conn.Close()

执行有参数“存储过程”的代码:

'连接数据库
        Dim conn As New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=F:\position.mdb;Jet OLEDB:Database Password=#")
        '打开数据库
        conn.Open()
        '生成命令
        Dim cmd As New OleDbCommand()
        cmd.CommandType = CommandType.StoredProcedure '设置使用存储过程
        cmd.Connection = conn
        cmd.CommandText = "StoredProcedureWithParameters" '存储过(查询对象)的名称
        cmd.Parameters.Add("@cityer", OleDbType.VarChar, 5).Value = "物主"
        cmd.Parameters.Add("@cityerr", OleDbType.VarChar, 10).Value = "天津"
        '执行命令
        Dim adapter As New OleDbDataAdapter()
        adapter.SelectCommand = cmd
        '填充DataTable
        Dim dt As New DataTable
        adapter.Fill(dt)
        DataGridView1.DataSource = dt
        '关闭数据库
        conn.Close()

可见,不能为了涂简便而使用拼接的方式组合SQL语句,很容易遭受SQL注入攻击,应该使用含参数Sql语句。

已标记关键词 清除标记
求各位大神给看一下~~ vb.net 绑定ACCESS数据库用到的控件是bindingnavigator、bindingsource、datagridview bindingnavigator用于点击删除增加保存按钮 bindingsource用于绑定数据源 datagridview用于显示数据表 程序代码如下: Imports System.Data.OleDb Public Class Frm Private Adapter As New OleDbDataAdapter Private Table As New DataTable Private Sub Frm_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load Table.Clear() Dim conn As OleDbConnection = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" &DBPath) Dim builder As OleDbCommandBuilder = New OleDbCommandBuilder(Adapter) Dim cmd As OleDbCommand = New OleDbCommand("Select * From 表", conn) Adapter.SelectCommand = cmd Adapter.Fill(Table) datagridview.AutoGenerateColumns = False bindingsource.DataSource = Table datagridview.DataSource = bindingsource bindingnavigator.BindingSource =bindingsource End Sub 以上可以成功绑定并显示数据表 bindingnavigator控件进行了绑定,所以可以直接点击上面的删除增加等按钮,删除某一行数据后点击下面保存是没问题的,数据库里面也确实删除了,但是进行修改或者增存一行数据后点击下面保存,数据库没有能更新数据,为什么能删除确不能修改和增加,不太清楚怎么回事了,哪位大神给解答一下,谢谢~~ Private Sub SaveChange_Click(sender As System.Object, e As System.EventArgs) Handles SaveChange.Click Adapter.Update(Table) datagridview.Refresh() End Sub End Class
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页