连接Access数据库
先用Access设计一个表,如下图:
表名:StudentInfo 文件名:Student.mdb,文件路径:d:\Data\Student.mdb
如果熟悉WINDOWS API的,可以去看一下如流,新一代智能工作平台
了解一下相关的知识点,这样关于什么连接字符串,项参数这些概念我也省得解释了。
C#连接不同的数据库,有不同的类。比如Access数据库就用OleDbConnection类来连接,而对应的SQL语句命令执行类就是OleDbCommand
而SQL Server则不同。
OleDbConnction和OleDbCommand类属于System.Data.OleDb命名空间。
看一个例子,将学生名为“Sean”的学生学号改为“S00009”。
新建一个控制台应用程序,代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.OleDb;
//OleDbConnection用来连接Access数据库
//OleDbCommand用来执行SQL语句命令
namespace TestConls
{
class Program
{
static void Main(string[] args)
{
//连接字符串
String strConn = "Provider=Microsoft.Jet.OleDb.4.0;";
strConn += "Data Source=d:\\Data\\Student.mdb";
//新建连接对象
OleDbConnection objConn = new OleDbConnection(strConn);
//连接数据库
objConn.Open();
//SQL语句
String SQL="Update StudentInfo Set StuNo='S00009' Where StuName='Sean'";
//新建执行objComm对象
OleDbCommand objComm = new OleDbCommand(SQL, objConn);
//执行SQL语句
objComm.ExecuteNonQuery();
//关闭数据库连接
objConn.Close();
}
}
}
关于字符连接的概念,Provider和Data Source是项参数,在字符串里要以分号来区分结尾。
Provider指的是数据提供者(驱动程序名称),这个是固定的,Access数据库填Microsoft.Jet.OleDb.4.0就行了。
而且Provider这个项参数也仅用于OleDbConnectioncf对象。
而Data Source是数据库文件路径名。如果是SQL Server,它指的是服务器名。
上面的连接字符串是通过OleDbConnection类的构造函数传进去的,其实也可以直接给
objConn.ConnectionString
赋值,事实上构造函数传进去的字符串,最终也是保存在obj.ConnectionString里面的。
那么同样的OleDbCommand构造函数传进去的两个参数也有对应的属性成员。
SQL语句是objComm.CommandText 连接对象是objComm.Connection
这样执行不同的SQL语句,只要给CommandText赋值就行了。然后再调用 objComm.ExecuteNonQuery();
另外ExecuteNonQuery()执行的SQL语句只限于非查询的,也就是不是从数据库获取数据的SQL语句。
比如Insert,UpDate这些SQL语句,就调用ExecuteNonQuery函数。
而类似Select * from这种要获取数据的语句得调用ExecuteReader函数。(后面再讲怎么获取数据库里的数据)
连接SQL Server数据库
SQL Server连接数据库的步骤跟Access一样,只不过它用来连接数据库的类变成了SqlConnection,对应的执行类是SqlCommand
它们属于System.Data.SqlClient命名空间。
我这里用的是SQL Server 2000数据库,首先建立一张跟前面Access数据库同样的表。
接着再来了解一下连接字符串里的几个参数属性。
Data Source是数据库服务器名称,在SQL Server连接里。它的别名有:"Address","Addr","Serve"。
一般SQL Server服务器名是以你的计算机名称来命名的。
看下图:
默认填(local)也行。上面我新建了一个数据库MyDatabase,并在其下建了一个表StudentInfo。
而参数Database就是指定是哪个数据库,MyDatabase还是master还是其它。它有一个别名是:"initial catalog"
user id和password,这是用户登录账号密码,如果不是采用Windows本地用户连接,则需要填用到这个两参数。它们的别名:uid和pwd
另:如果是Windows信任连接的话,Trusted_Connection参数应该赋值SSPI,指明Windows连接。也就是Trusted_Connection=SSPI
例子,读取一张表里的所有数据,并输出列名
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
namespace TestConls
{
class Program
{
static void Main(string[] args)
{
//连接Sql Server数据库
String strConn = "Server=(local);Database=MyDatabase;Trusted_Connection=SSPI";
SqlConnection sqlConn = new SqlConnection(strConn);
sqlConn.Open();
//执行SQL语句
String SQL="Select * from StudentInfo";
SqlCommand sqlComm = new SqlCommand(SQL, sqlConn);
SqlDataReader sqlReader = sqlComm.ExecuteReader();
//输出数据
for (int i = 0; i < sqlReader.FieldCount; i++)
{
//输出列名
Console.Write("{0,-13}", sqlReader.GetName(i));
}
Console.Write("\n");
//读取一行,没有下一行返回false
while (sqlReader.Read())
{
for (int i = 0; i < sqlReader.FieldCount; i++)
//输出数据
Console.Write("{0,-13}", sqlReader[i].ToString());
Console.Write("\n");
}
sqlReader.Close();
sqlConn.Close();
}
}
}
运行效果图:
这一次执行SQL语句用的是ExecuteReader函数,这个函数返回一个SqlDataReader 类对象,这个对象就记录着所获取的表数据了。
SqlDataReader类里的FieldCount储存表的列数量。
而GetName函数获取列名,参数指明获取哪一列的列名。
然后调用Read函数读取一行数据。上面是通过sqlReader[i](索引器)的方式获取具体数据的,还可以用GetString函数,如获取当前行第二列的数据就是sqlReader.GetString(1);
获取具体数据也可以用这种方式,索引用列名,如sqlReader["StuNo"],这个是一行的StuNo列值。
使用SqlDataAdapter和DataSet获取数据
连接数据库的步骤都是一样的,只不过是用SqlDataAdapter代替了SqlCommand,也可以说是SqlDataAdapter包含了SqlCommand。
SqlDataAdapter的创建如下:
SqlDataAdapter da = new SqlDataAdapter(SQL, sqlConn);
也可以用这种方式:
SqlDataAdapter da=new SqlDataAdapter();
da.SelectCommand = new SqlCommand(SQL, sqlConn);
第一种方式其实也是采用的第二种方试,它在构造函数里建立了一个SqlCommand对象,然后传递给SelectCommand。
建立好了SqlDataAdapter后,接着创建DataSet对象,这个对象用来储存数据表,它可以储存多张表。多张表对应着它的属性成员Tables。
创建DataSet对象:
DataSet ds = new DataSet();
接着把SqlDataAdapter获取的数据表填充到DataSet对应表里(新建的表)。
da.Fill(ds, "newStuInfo");//newStuInfo是在DataSet新建的表名字,可随便取名。
接着我们就可以来读取DataSet里的newStuInfo表数据了。
如第一行一例就是:ds.Tables["newStuInfo"].Rows[0][0] 这是一个object类型,object可以转换成对应的类型。
而ds.Tables["newStuInfo"]是DataTable类型。DataTable类里一个Rows属性成员代表行,Rows[0]表示第一行,Rows[1]表示第二行。
Rows[0]是DataRow类型。Rows[0][0]就表示,第一行一列,那么一行二列就是Rows[0][1],也可以用列名作列的索引。
如:Rows[0]["StuNo"]; Rows.Count记录行数。
对应的,DataTable类也有个列的属性成员Columns,Columns.Count记录列数。
另外Columns记录着列名,比如第一列列名就是:Columns[0],它的类型是DataColumn
看例子:获取一张表里的所有数据
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
namespace TestConls
{
class Program
{
static void Main(string[] args)
{
//连接Sql Server数据库
String strConn = "Server=(local);Database=MyDatabase;Trusted_Connection=SSPI";
SqlConnection sqlConn = new SqlConnection(strConn);
sqlConn.Open();
//执行SQL语句
String SQL="Select * from StudentInfo";
SqlDataAdapter da = new SqlDataAdapter(SQL, sqlConn);
//创建DataSet对应表
DataSet ds = new DataSet();
da.Fill(ds, "newStuInfo");
//输出列名
DataTable dt = ds.Tables["newStuInfo"];
for (int i = 0; i < dt.Columns.Count; i++)
Console.Write("{0,-13}", dt.Columns[0]);
Console.Write("\n");
//输出具体数据
foreach (DataRow dRow in dt.Rows)
{
//dRow[dCols]其实就是以列名作索引的方式来访问,就是dRow["StuNo"];
//我这里用的是foreach方式获取数据,也可以用dt[0][0]方式来访问,
//如上面获取列名的方式。
foreach(DataColumn dCol in dt.Columns)
Console.Write("{0,-13}",dRow[dCol]);
Console.Write("\n");
}
sqlConn.Close();
}
}
}
使用SqlDataAdapter和DataSet更新数据
只要更改DataSet里表的值,然后再调用SqlDataAdapter类里的Update函数就可以更新数据库了。
不过前提是要创建个SqlCommandBuilder对象,这个对象用于监测数据库表是否改动,然后再生成相应的SQL语句。
另外,要使Update生效的话,数据库表必须要有主键,没设置主键的赶紧去设置主键吧。
示例代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
namespace TestConls2
{
class Program
{
static void Main(string[] args)
{
//连接Sql Server数据库
String strConn = "Server=(local);Database=MyDatabase;Trusted_Connection=SSPI";
SqlConnection sqlConn = new SqlConnection(strConn);
sqlConn.Open();
//执行SQL语句
String SQL = "Select * from StudentInfo";
SqlDataAdapter da = new SqlDataAdapter(SQL, sqlConn);
//创建SqlCommandBuilder对象,跟da关联
SqlCommandBuilder cb = new SqlCommandBuilder(da);
//创建DataSet对应表
DataSet ds = new DataSet();
da.Fill(ds, "newStuInfo");
//修改ds里newStunInfo表的数据
ds.Tables["newStuInfo"].Rows[0]["StuName"] = "Abc";
//把newStuInfo表更新到原表里去。
da.Update(ds, "newStuInfo");
sqlConn.Close();
}
}
}
另外ExecuteScalar用于执行只返回一个值的SQL语句,比如求平均分,求总和的SQL语句。