分享
 
 
 

细说ADO.NET命令

王朝c#·作者佚名  2008-06-01
窄屏简体版  字體: |||超大  

在ADO中,有三种可能方式用于更新数据源。一个是通过直接SQL语句,如INSERT, DELETE 或 UPDATE,或稍复杂、较成熟的存储过程。另一个是通过批更新,你一次可以向服务器递交某个表的新映射。第三个方法是使用服务器指针直接对字段更新。

ADO .NET完全支持前两种技术,这涉及到不是的对象和方法。至于服务器指针,需要做进一步的讨论和确认,但到目前为止,在ADO .NET中它们只得到有限的支持。

下面开始分析在ADO .NET中更新数据源的方法和技术。本月,我将重点放在直接SQL命令和存储过程上。在以后的专栏中,我将同时具体介绍批更新和服务器指针。

OLE DB 和"治理"提供者

ADO .NET并不直接支持OLE DB提供者,但这并不是说你不能从ADO .NET中访问OLE DB提供者。对此,我只是要表明一个非凡的治理提供者总是对访问任何现有的有效OLE DB提供的调用进行预处理。出于这个原因,你的ADO .NET永远不会直接作为一个OLE DB客户。

治理提供者是在.NET中工作的一种模块,它的工作方式与OLE DB在Win32? 和 COM环境中的工作方式相同。从任何角度来说,治理提供者是OLE DB的.NET对应物。它们是简化了的组件,并不象OLE DB那样遵循复杂的通用的规范(如通用数据访问)。

更重要的是,治理提供者完全能在.NET的通用语言运行时(Common Language Runtime ,CLR)环境中工作。相反,OLE DB提供者是一个老COM对象,在.NET环境中,它只能运行在非治理窗口中。

为了访问ADO.NET中的数据,你应当遵循典型ADO会话中的同样步骤。首先,创建链接,通过连接字符串指定参数。接着,实例化命令对象,设置正确的命令字和行为,然后执行。最后,根据命令的期望输出,或者你操纵结果,或者关闭链接,将其余工作留给应用程序。 注重,在ADO中可以减少一些步骤,如直接调用Connection对象的Execute方法。这种做法在ADO .NET中是不答应的,因为并不是所有类型的Connection对象具有Execute方法。

不同类型的链接对象?这又意味着什么呢?

ADO .NET要求你在链接时事先知道并指定将链接到的(治理)数据提供者的类型。在ADO中,你拥有Connection对象,这就足够了,而不必考虑获得和设置数据的物理通道。不论是使用OLE DB ,还是归结为ODBC,通过供ODBC使用的通用OLE DB提供者,ADO 总是要求使用同种类型的Connection对象。在ADO .NET中情况就不是这样了。

到目前为止,有两种类型的治理提供者,一个专门用于SQL Server 7.0 和 2000,另一个用于访问任何OLE DB提供者。通过治理提供者,轻易辨别出这种设计方式与在ADO中答应ODBC数据源访问OLE DB的方式是相同的。

用于访问ODBC数据源的第三方治理提供者现在处于测试阶段。事实上,用于OLE DB的治理提供者不支持ADO中用于同ODBC驱动对话的MSDASQL OLE DB提供者。

SQL Server是在System.Data.SqlClient名称空间中定义它的类的。OLE DB 治理提供者大部分定义在System.Data.OleDb名称空间中。

在ADO .NET中,不存在通用而又有用的链接类。存在一个DBConnection类,其它其它特定于提供者的链接类从该类派生,但它是一个抽象类。作为原形设计,它是有用的,但它不会直接在应用程序中使用。

因此,为打开一个链接,必须使用下面的两个方法之一:SqlConnection 方法和 OleDbConnection方法。假如目标是SQL Server 7.0, SQL Server 2000或更高版本,使用前者。假如目标是OLE DB提供者,就应当使用后者。假如需要通过ODBC驱动器访问数据,就要使用ODBC .NET提供者的链接类(名为OdbcConnection)。

要访问SQL Server数据库,使用直接治理提供者将产生更加有效的代码。然而,注重假如需要访问SQL Server6.5,那么就必须求助于OLE DB提供者,并使用OleDbXxx类和用于OLE DB的治理提供者。

因此,在ADO .NET中有许多成对的类,如SqlConnection 和 OleDbConnection, SqlCommand 和 OleDbCommand, SqlDataReader 和 OleDbDataReader等等。尽管不同的对间最大的不同可能在于它的前缀,但假如说它们对编程接口是相同的,却是不对的。

可以确定的是,每对类做同样的事情,但它们所有的接口反映的是底层的数据提供者。例如,在SqlConnection对象上没有Provider属性,而在类中没有PacketSize 或 WorkStationId 概念。

在本文的后面部分,我将使用SQL Server治理提供者,这将意味着面向数据的ADO .NET类将带有Sql前缀。在先前否认声明有效的前提下,不需要对代码进行修改或进行有限修改,它就能工作,对于由OLE DB提供者暴露的数据源也是一样的。

链接到数据源

如同期望的那样,需要链接对象将命令发送到SQL Server数据库。从β2版开始,链接只能是SqlConnection类的对象。你将不再能通过向命令发送链接字符串,暗中创建链接对象。

strConnString = "DATABASE=MyDB;SERVER=localhost;UID=sa;";

SqlConnection conn = new SqlConnection(strConnString);

strCmdText = "INSERT INTO MyTable VALUES (1, '1', 'One')"

SqlCommand cmd = new SqlCommand(strCmdText, conn);

在这段代码片段中,我明确创建了一个链接对象,并将它与一个新的命令对象联结起来。链接对象通过SqlCommand的Connection属性暴露。

在打开链接开始工作前,你可能要设置一些属性。

cmd.Connection.Open();

在 ADO .NET中,链接对象的Open 方法不需要参数。

至于链接对象的重用性,记住,ADO .NET提供了一种链接池。在以后的专栏中我将对它做进一步的讨论,至于现在,你只要不必为节省对象的创建重用链接就可以了。不论何时客户端需要一个链接,返回的是链接池中的对象。一旦链接关闭,对象不是留给碎片收集器,而是释放到池中,供其它调用者使用。 链接池不是由ADO .NET直接治理。SQL Server链接依靠Windows? 2000服务组件地pooling服务。每个链接池通过确切的匹配法则与不同的链接字符串相关。一旦创建,SQL Server链接池至到活动过程终止,它才会终结。

相反,OLE DB链接被很小心的集中在OLE DB提供者会话对象的内部实现中。会话集中和自动收集是通过OLE DB服务完成,并通过注册设置在每一个提供者基础上被激活。因此,自动链接池并不会发生在所有OLE DB 提供者上,所有设备上。

关于链接对象,最后要指出的是,链接类是不可继续的。你不能从SqlConnection 或 OleDbConnection中创建一个新类。这样做是出于代码安全方面的考虑。然而,你可以创建你自己的类,在类中包含一个或多个链接对象。使用直接命令

在向数据提供者发送命令前,要确保链接已经打开。默认链接是关闭的。然后,执行命令,只要有可能就关闭链接以确保其他客户能得到重要资源。

SqlCommand类提供了用于执行命令的四个方法。它们是:ExecuteReader, ExecuteNonQuery, ExecuteScalar,及最新的但不是最小的,ExecuteXMLReader。从本质上讲,这些方法在期望的输入上不同,返回的结果不同而已。通常,在操作完成后,需要确定使用的方法而不是继续向前。

顺便指出,OleDbCommand 对象不支持ExecuteXmlReader。

ExecuteReader用于执行选择记录的查询命令或存储过程。它返回一个或多个结果集。

cmd.Connection.Open();

SqlDataReader dr = cmd.ExecuteReader();

// 处理结果集

cmd.Connection.Close();

你可以通过SqlDataReader对象访问选择的记录,使用Read方法在记录间循环。使用NextResults方法移动到下一结果集。

ExecuteNonQuery用于执行命令或存储过程,它影响特定表的状态。这只意味着一个查询命令。通常使用此方法执行INSERT, UPDATE, DELETE, CREATE, SET语句。

ExecuteNonQuery只返回命令所影响到的行数,假如得不到信息则返回-1。它并不能使你访问语句或存储过程生成的结果集。实际上,无法阻止你用此方法执行一条查询命令,但在这种情况下,你既得不到结果集也得不到被影响的行数。

cmd.Connection.Open();

nRecsAffected = cmd.ExecuteNonQuery();

cmd.Connection.Close();

//此处检查影响到的记录

通过SqlCommand对象的RecordsAffected属性可以得到影响到的行数。假如发生错误或假如执行的昌查询命令,此属性值为-1。

ExecuteScalar期望执行查询命令,或更可能是一个存储过程,它返回数据。然而,此方法与ExecuteReader方法不同,它只将得到的结果集中的第一行第一列的值作为标量值返回。

cmd.Connection.Open();

Object o = cmd.ExecuteScalar();

cmd.Connection.Close();

// work on the scalar here

此方法将值作为一个封装对象返回。然后由你来解包或将此值造型为正确的期望类型。

假如需要对数据执行具有统计或集合性质的操作,ExecuteScalar方法将非凡有用。在这些或相似的情况下,你可能只希望返回给调用者一个值。由于它的使用场合,你或多或少的对存储过程而不是单个SQL语句使用此方法。

ExecuteXmlReader方法在SELECT命令执行后,构建并返回一个XmlReader对象,它利用了存在于SQL Server 2000中的XML特性。使用存储过程

到目前为止,对存储过程讨论得已经够多了,是该看一下如何在ADO .NET中使用它了。在ADO .NET中调用存储过程只与常规SQL语句稍微不同。

你应当将存储过程的名字指定为SqlCommand对象的命令文本。命令文本可以通过SqlCommand的构造函数或通过CommandText属性指定。在下面的示例代码中,存储过程的名字是byroyalty。

SqlCommand cmd = new SqlCommand("byroyalty", conn);

cmd.CommandType = CommandType.StoredProcedure;

SqlParameter par = new SqlParameter("@percentage", SqlDBType.Int);

par.Direction = ParameterDirection.Input;

par.Value = 15;

cmd.Parameters.Add(par);

SqlDataReader dr = cmd.ExecuteReader();

为帮助SqlCommand辨认出将执行的命令是一个存储过程,应当将CommandType属性设置为特定的值。

CommandType.StoredProcedure

它是在CommandType枚举值(即可以在ADO .NET中使用的所有可以得到的命令类型)中的一个值。

存储过程可能需要一个或多个参数才能运行。在这种情况下,你需要使用SqlParameter类定义参数。

参数具有@前缀名,并是与SQL Server兼容的类型。另外,它还要有一个方向:输入,输出还是两种都有,当然它得是一个值。.NET 类型系统不同于SQL Server类型系统,你必须求助于SqlDbType枚举列表得到正确的类型。例如,下面的片断对.NET32位整型求值。

SqlDbType.Int

SqlCommand 类拥有Parameters集合,此集合为SQL命令的占位符和存储过程是定义的所有参数存储实际的值。要向集合中增加参数,只需调用add方法。注重,假如你以SQL Server治理提供者或用于OLE DB .NET提供者的位置标记为目标,那么在命令命令文本中你必须使用已命名的参数。

存储过程的输出然后通过你所使用的ExecuteXXX方法提供的接口进行治理。

其它 SqlCommand 属性

下面介绍在SqlCommand类中发现的其它有趣的属性。

一条命令在过一定时间后就会超时。假如你知道要经过很长的操作,你就可能希望设置这种限制。象ADO中那样,检查的属性是CommandTimeout,其默认值是30秒。

与ADO不同,ADO .NET使你可通过CommandBehavior枚举指定命令的期望行为。这样的值指定了对结果的描述,并指定查询如何影响数据源。在β1版本中,可以为每个命令设置CommandBehavior属性。从β2版开始,只能使用CommandBehavior枚举值作为ExecuteReader的参数。

对于其它选项,你可以使用查询命令限制获得的要害字和结构信息。在这种情况下,命令执行时不会对选择的行进行锁定。这种行为是由KeyInfo标记设定的。

作为可选项,可能只需得到列信息,而不通过加锁影响数据库的状态。这个选项是SchemaOnly。另一个选项,SingleResult,使你能够指定只返回一个结果集,而不论命令可以得到多少个结果集。在这种情况下,命令只返回找到的第一个结果集。第四个选项是CloseConnection,它强迫SqlDataReader对象与一个查询命令联结起来,以期望在Close方法的最后一步自动关闭链接。

服务器指针

先前提到过,在ADO .NET中不支持服务器指针。假如需要使用服务器指针,并且负担不起在没有它的情况下重建应用程序,唯一的办法是通过ADO对象。要这样做,需要导入ADODB类型库,为不同的对象创建恰当的.NET封装,然后与它们连接起来。然而,在这种情况下,你无法利用ADO .NET的优势。

这样做原因很简单。服务器指针必须与数据库服务器的底层行为相适应。当处于链接时,并不是所有的DBMS以同样的方式工作。这样不同特性的对数据库不可知的实现已经证实是非常困难的。为了避免出现更进一步的问题,ADO .NET没有为服务器指针暴露通用的类,从而从根本上消除了这种问题。

然而,用于SQL Server的治理提供者在将来的发行版中将支持服务器指针,其它类型的治理提供者也会发生同样的事情。因此,ADO .NET对服务器指针支持的最后回答是,它将提供支持,但是将通过其实现与底层工作方式非常匹配的类以一种严格的完全DBMS方式(提供支持)。

总结

在ADO .NET中浏览数据的方式并不真正与在ADO中的方式不同。你仍需要创建链接,发送命令。在本文中,我提到了表示直接SQL命令的类,你可以使用它们执行存储过程。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有