您的位置:首页 > 数据库

初学者读书笔记数据库篇(一)

2005-04-26 08:58 393 查看
不管学习什么知识,基础最重要,一切要从基础开始,否则只会是空中楼阁。以下是我看《.net程序设计技术内幕》数据库篇的读书笔记。 

   .net框架对数据库的操作主要是靠ADO.NET完成的,而ADO.NET的数据库访问是通过被称为数据提供程序(data provider)的软件模块来进行的。

.net框架的1.0版本有两个数据提供程序:

1,SQL Server .NET提供程序 它是于Microsoft SQL Server数据库的接口,不需要任何非托管提供程序的帮助。

2,OLE DB .NET提供程序  它是通过OLE DB提供程序访问数据库的接口。

 其中OLE DB.NET提供程序允许我们通过从托管代码中调用现有的OLE DB提供程序来使用它们:

  1,SQLOLEDB提供程序  它是与SQL Server数据库的接口

  2,MSDAORA提供程序   它是与Oracle数据库的接口

  3,Microsoft.jet,OLEDB.4.0提供程序  它是与通过Microsoft Jet数据库引擎驱动的数据库的接口

如果应用程序会使用Microsoft SQL 7.0或者以上的版本,则使用SQL Server .NET提供程序。它比OLE DB提供程序快。它在访问数据库时候不离开托管代码的领域,相反,OLE DB .NET提供程序使用 .NET框架的Platform Invoke机制调用非托管的OLE DB提供程序;如果应用程序使用Microsoft SQL 6.5或者是以前版本,选择OLE DB.NET提供程序;如果应用程序使用非SQL Server数据库,比如Oracle 8i,选择OLE DB.NET提供程序。

以下是操作SQL Server 7.0,使用SQL Server .NET提供程序或OLE DB .NET提供程序的数据库操作实例代码

使用SQL Server .NET提供程序

using System.Data.SqlClient

...

SqlConnection conn=new SqlConnection("server=localhost;database=pubs;uid=sa;pwd='');

try

{

conn.open();

SqlCommand cmd=new SqlCommand("select * from titles",conn);

SqlDataReader reader=cmd.ExecuteReader();

while(reader.read())

{

Console.WriteLine(reader["title"]);

}

catch(SqlException ex)

{

Console.WriteLine(ex.Message);

}

finally

{

conn.close();

}

}

使用OLE DB .NET提供程序

using System.Data.OleDb;

...

OleDbConnection conn=new OleDbConnection("provider=sqloledb;server=localhost;database=pubs;uid=sa;pwd='');

try

{

conn.open();

OleDbCommand cmd=new OleDbCommand("select * from titles",conn);

OleDbDataReader reader=cmd.ExecuteReader();

while(reader.read())

{

Console.WriteLine(reader["title"]);

}

catch(OleDbException ex)

{

Console.WriteLine(ex.Message);

}

finally

{

conn.close();

}

}

可以看到除了类名和连接字符串以外,两个提供程序之间对操作sql server 7没有什么其他的不同,说明了ADO.NET为不同的类型的数据库提供了一个通用的API,这个API的细节有些会不同,这取决于我们使用的托管提供程序。

1,连接

SqlConnection conn=new SqlConnection("server=localhost;database=pubs;uid=sa;pwd='');

此为一个SqlConnection有参数的构造函数,参数其实可以是连接conn的一个属性ConnectionString,其中这个字符串的格式要正确

在打开连接的时候会验证这个字符串,如果不通过会产生一个异常。

server=localhost可以写成server=(local)或Data Source=(local);database参数可以写成Initial Catalog,uid可以写成user id,pwd可以写成password。

对于oledb提供程序也是类似的连接方式:OleDbConnection conn=new OleDbConnection("provider=sqloledb;server=localhost;database=pubs;uid=sa;pwd='');

Provider参数标识了用于和数据库交互的Ole Db提供程序-这里是SQLOLEDB,它是微软面向SQL Server的OLE DB提供程序。把提供程更改成MSDARA就会把目标改成Oracle数据库。

创建了一个SqlConnection或OleDbConnection对象和提供一个连接字符串并没有打开一个指向数据库的物理连接,必须调用对象的Open方法才能做到这点。用Open打开的连接最好用Close关闭。

如果不能建立一个指向数据库的连接,Open方法会引发异常,而且打开连接在数据库上执行的操作如果失败,也会引发异常,应该对异常进行捕捉。

所以一般对数据库的操作代码一般为:

SqlConnection conn=new SqlConnection("server=localhost;database=pubs;uid=sa;pwd='');

try

{

conn.open();

//TODO:使用连接

}

catch(SqlException ex) //我们有必要关心一下SqlException的属性

{

//TODO:处理异常

}

finally

{

conn.close();

}

}

对OLE DB .NET提供程序的等价代码如下:

OleDbConnection conn=new SqlConnection("server=localhost;database=pubs;uid=sa;pwd='');

try

{

conn.open();

//TODO:使用连接

}

catch(OleDbException ex)

{

//TODO:处理异常

}

finally

{

conn.close();

}

}

2.使用命令(类为SqlCommand或OleDbCommand)

使用ExecuteNonQuery方法,此方法用来执行INSERT,UPDATE,DELETE和其他没有返回值的SQL命令(比如CREATE DATABASE和CREATE TABLE命令)

此方法返回被命令影响的行数。要使用ExecuteNonQuery创建名为MyDatabase的新数据库,只需要将命令对象的命令为本改为"create database MyDatabase",接着使用create table和insert命令来建立表和插入数据了。

如果ExecuteNonQuery失败,也会产生SqlException或OleDbException对象异常。注意:带有无效字段的update命令和违反主键约束规则的insert命令会引起异常,但是以不存在的记录为目标update和delete命令不够成错误,只是ExecuteNonQuery

返回o.

使用ExecuteScalar方法,此方法执行一个SQL命令并返回结果集的第一列的第一行,而忽视其他的列和行。它最常用来执行Sql的count,avg,min,max和sum等集函数,因为这些函数都是返回单行单列的结果集。

值得我们注意的是ExecuteScalar方法返回的是一个Object类型,所以我们在使用的时候要把它返回的结果强制转换成所需要的类型。如果转换不正确,.net框架就会引发InvalidCastException异常。

这个方法还有一个比较普遍的用法是从数据库中检索BLOB(二进制大对象).看如下代码:

MemoryStream stream=new MemoryStream();

SqlConnection conn=new SqlConnection("server=localhost;database=pubs;uid=sa;pwd='');

try

{

conn.Open();

SqlCommand cmd=new SqlCommand("select logo from pub_info where pub_info='0763'",conn);

byte[] blob=(byte[])cmd.ExecuteScalar();

stream.Write(blob,0,blob.Length);

Bitmap bitmap=new Bitmap(stream);

bitmap.Dispose();

}

catch(SqlException ex)

{

//TODO:处理异常

}

finally

{

stream.Close();

conn.Close();

}

这样就创建了一个位图。

随便写出如何将blob写入数据库的代码:

SqlConnection conn=new SqlConnection("server=localhost;database=pubs;uid=sa;pwd='');

try

{

conn.Open();

SqlCommand cmd=new SqlCommand("insert into pub_info (pub_id,logo) values('9937',@logo)",conn)//使用参数化命令

cmd.Parameters("@logo",blob);

cmd.ExecuteNonQuery();

}

catch(...)

{

...

}

finally

{

conn.Close();

}

变量blob是单独定义和初始化的,下面是从logo.jpg文件中读取图像:

FileStream stream=new FileStream("logo.jpg",FileMode.Open);

Byte[] blob=new byte[stream.Length];

stream.Read(blob,0,(int)stream.Length);

stream.Close();

使用ExecuteReader方法,此方法存在的目的只有一个,尽可能快的对数据库进行查询并得到结果,返回一个DataReader对象。它是一个快速枚举数据库查询结果的机制,

是只读、只进的。生成的DataRead对象是一个开始指向记录集的空项数据的,必须使用Read()方法进行指针的移动来显示数据。

如:

SqlConnection conn=new SqlConnection("server=localhost;database=pubs;uid=sa;pwd='');

try

{

conn.open();

SqlCommand cmd=new SqlCommand("select * from titles",conn);

SqlDataReader reader=cmd.ExecuteReader();

while(reader.read())   ///读到最后一条数据以后再reader.read()返回值就会为false退出循环

{

Console.WriteLine(reader["title"]);  ///也可以使用索引reader[0]表示此行第一列的数据

}

catch(SqlException ex)

{

Console.WriteLine(ex.Message);

}

finally

{

conn.close();

}

}

而且在用DataReader查询数据库之前不需要预先知道它的架构,可以使用这个对象来获得架构信息。使用函数DataReader对象的属性FieldCount来获得该行的列的数目,然后使用方法GetName(int i)来返回索引为i的列的名字。还可以使用GetSchemaTable()方法来获得构架信息,该方法返回一个DataTable对象。

int index=DataReader.GetOrdinal("属性名")来返回该属性名对应的索引。

GetDecimal(index)获得该行索引值为index的属性列的值。

值得注意的是DataReader对象必须在数据库处于连接状态下才能运行的,所以在查询语句之前不可能出现conn.Close(),而且如果你用一个命令创建了一个DataReader对象以后,又想用那个命令

对象作别的事情,那么必须现关闭创建的DataReader对象Reader.close(),然后再进行其他的操作。

还可以使用DataReader关闭底层连接,代码:reader=cmd.ExecuteReader(CommandBehavior.CloseConnection);此时必须把reader.Close()放在finally块中以防止由于泄露连接引发异常。

不好意思,写得有点乱望斧正。

为什么我不能插入代码??
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: