仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 496|回复: 7
打印 上一主题 下一主题

[学习教程] ASP.NET教程之利用 ADO.NET 会见 Oracle 9i 存储历程...

[复制链接]
分手快乐 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-16 22:34:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
不过你如果学.net的话,你就不要选os了,这课比较底层的。你可以旁听数据库加上软件构件和中间件。(webservices和面向服务的课也应该听一听)ado|oracle|存储历程|会见  择要:利用Microsoft.NET框架1.1中的Microsoft.NETOracle供应程序会见Oracle存储历程和函数。
  本文会商了怎样利用ADO.NET会见Oracle存储历程(称为SQL编程块)和函数(前往单个值的编程块)。
  您可使用以下托管数据供应程序毗连到Oracle数据库:Microsoft.NETOracle供应程序、OLEDB.NET供应程序、ODBC.NET数据供应程序和Oracle的ODP.NET供应程序。本文利用用于Oracle的Microsoft?.NET框架数据供应程序。利用OracleODP.NET数据供应程序或用于OLEDB的Microsoft.NET框架数据供应程序时可以使用分歧的功效。
  Oracle.NET数据供应程序随.NET框架1.1一同供应。假如您利用的是.NET框架1.0,您将必要下载.NETManagedProviderforOracle。不管是哪一个版本,数据供应程序类都位于System.Data.OracleClient定名空间中。
  概述
  PL/SQL是SQL的Oracle完成。它与Microsoft?SQLServer?所利用的T-SQL相似,但也有一些分歧的地方,本文稍后对此举行了具体会商。与T-SQL一样,PL/SQL扩大了尺度SQL。PL/SQL用于界说定名编程块,如存储历程、函数和触发器。
  类
  可以使用System.Data.OracleClient定名空间中类的子集来实行Oracle存储历程和函数。下表对这些类举行了申明:
类申明OracleCommand
针对Oracle数据库实行的存储历程的SQL语句。
OracleConnection
翻开的数据库毗连。
OracleParameter
OracleCommand的参数,也多是它到DataColumn的映照。
OracleParameterCollection
OracleParameter工具的汇合。
OracleType
Oracle数据范例和布局的列举。

  实行存储历程
  实行Oracle存储历程与实行SQLServer存储历程相似。上面的步骤申明了怎样实行Oracle存储历程和检索它前往的了局。
  1.在HR架构中创立一个名为COUNT_JOB_HISTORY的存储历程,以盘算JOB_HISTORY表中的纪录数。
CREATEORnewPROCEDURECOUNT_JOB_HISTORY
(
reccountOUTNUMBER
)
IS
BEGIN
SELECTCOUNT(*)INTOreccount
FROMJOB_HISTORY;
ENDCOUNT_JOB_HISTORY;
  HR架构是默许Oracle安装中包括的一个示例。

  2.将System.Data.OracleClient.dll(用于Oracle的Microsoft.NET框架数据供应程序)的援用增加到项目中。

  3.利用using指令导进OracleClient类中的范例。
usingSystem.Data.OracleClient;
  4.创立一个OracleConnection工具。
OracleConnectionconn=newOracleConnection("DataSource=oracledb;
UserId=UserID;Password=Password;");
  用您的值交换Oracle数据库的称号、用户名和暗码。

  5.创立一个OracleCommand工具。将其Connection属性设置为第4步中创立的毗连。将其CommandText设置为存储历程的称号,并将其CommandText属性设置为CommandType.StoredProcedure。当您挪用第8步中先容的一个Execute()办法时,该命令工具将实行指定的存储历程。
OracleCommandcmd=newOracleCommand();
cmd.Connection=conn;
cmd.CommandText="COUNT_JOB_HISTORY";
cmd.CommandType=CommandType.StoredProcedure;
  假如您的存储历程称号含有特别字符,您就必需利用本义序列。您能够经由过程重置CommandText属性来重用现有的OracleCommand工具。

  6.创立输出、输入和前往值的OracleParameter工具,并将其增加到OracleCommand工具的参数汇合中。
cmd.Parameters.Add("reccount",OracleType.Number).Direction=
ParameterDirection.Output;
  该行代码是以下两行代码的简写情势:
cmd.Parameters.Add("reccount",OracleType.Number);
cmd.Parameters["reccount"].Direction=ParameterDirection.Output;
  7.假如您要检索了局集,请创立DataSet、DataTable或DataReader。在本示例中,我们只是猎取第6步中创立的输入参数中的计数。
  8.利用OracleCommand工具的一个Execute办法翻开毗连并实行存储历程,以下所示:
办法申明ExecuteReader
经由过程实行可以前往了局集的存储历程天生OracleDataReader
ExecuteNonQuery
实行不前往了局集的查询或历程,前往受影响的行数。
ExecuteOracleNonQuery
实行查询,前往受影响的行数。
该办法还利用OracleString参数来前往UPDATEINSERTDELETE查询所修正的最初一行的行ID。
ExecuteScalar
实行一个查询或历程,而且前往查询或历程的前往值,大概将了局集第一行第一列的值作为.NET框架数据范例前往。
ExecuteOracleScalar
实行一个查询或历程,而且前往查询或历程的前往值,大概将了局集第一行第一列的值作为OracleType数据范例前往。

  利用完毗连后,不要健忘将其封闭。
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
  假如您要利用DataAdapter来添补DataTable或DataSet,能够依托DataAdapter来翻开和封闭毗连。

  9.处置了局。在我们的示例中,可在显现到把持台的输入参数中失掉纪录数:
Console.WriteLine(cmd.Parameters["reccount"].Value);
  上面是在本示例中开辟的用于实行存储历程和检索了局的代码:
OracleConnectionconn=newOracleConnection("DataSource=oracledb;
UserId=UserID;Password=Password;");
OracleCommandcmd=newOracleCommand();
cmd.Connection=conn;
cmd.CommandText="COUNT_JOB_HISTORY";
cmd.CommandType=CommandType.StoredProcedure;
cmd.Parameters.Add("reccount",OracleType.Number).Direction=
ParameterDirection.Output;
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
Console.WriteLine(cmd.Parameters["reccount"].Value);
  不前往数据的存储历程
  OracleCommand类的ExecuteOracleNonQuery()办法用于实行不前往任何行的SQL语句或存储历程。该办法前往一个int值,暗示受UPDATE、INSERT和DELETE命令影响的行数;假如没有任何行遭到影响,则前往-1。假如您所实行的INSERT、DELETE或UPDATE语句刚好影响一行,则该办法具有单个参数OracleStringoutrowid,该参数独一标识Oracle数据库中受影响的行。可使用该值来优化后续相干查询。
  还可使用OracleCommand类的ExecuteNonQuery()办法来实行不前往数据的存储历程,但您将没法取得下面先容的独一行标识符。
  只管上述命令都不会前往任何数据,但映照到参数的输入参数和前往值仍旧利用数据举行添补。这使您可使用上述任一命令从存储历程前往一个或多个标量值。
  以下Oracle存储历程删除由单个输出参数指定的员工的一切事情履历,而且不前往任何数据。
CREATEORnewPROCEDUREDELETE_JOB_HISTORY
(
p_employee_idNUMBER
)
IS
BEGIN
DELETEFROMjob_history
WHEREemployee_id=p_employee_id;
ENDDELETE_JOB_HISTORY;
  以下代码运转了该存储历程。
//createtheconnection
OracleConnectionconn=newOracleConnection("DataSource=oracledb;
UserId=UserID;Password=Password;");
//createthecommandforthestoredprocedure
OracleCommandcmd=newOracleCommand();
cmd.Connection=conn;
cmd.CommandText="COUNT_JOB_HISTORY";
cmd.CommandType=CommandType.StoredProcedure;
//addtheparameterspecifyingtheemployeeforwhomtodeleterecords
cmd.Parameters.Add("p_employee_id",OracleType.Number).Value=102;
OracleStringrowId;
//executethestoredprocedure
conn.Open();
introwsAffected=cmd.ExecuteNonQuery();
conn.Close();
Console.WriteLine("Rowsaffected:"+rowsAffected);
  假如您还没有修正默许的HR安装,则JOB_HISTORY表中员工102的纪录被删除,而且向把持台输入以下内容:
Rowsaffected:1
  会见前往值
  RETURN语句当即将把持从存储历程前往到挪用程序。Oracle存储过程当中的RETURN语句没法像在T-SQL中那样前往值。
  Oracle函数是盘算并前往单个值的子程序。它们的布局相似于存储历程,分歧的地方在于它们老是具有必需前往值的RETURN子句。
  上面是一个前往指定员工的电子邮件的函数:
CREATEORnewFUNCTIONGET_EMPLOYEE_EMAIL(
p_employee_idNUMBER
)
RETURNVARCHAR2
ISp_emailVARCHAR2(25);
BEGIN
SELECTEMAILINTOp_emailFROMEMPLOYEES
WHEREEMPLOYEE_ID=p_employee_id;

RETURNp_email;
ENDGET_EMPLOYEE_EMAIL;
  实行函数的体例与实行存储历程的体例不异。可以使用ParameterDirection.ReturnValue参数取得由函数前往的了局。以下代码显现了利用办法:
//createtheconnection
OracleConnectionconn=newOracleConnection("DataSource=oracledb;
UserId=UserID;Password=Password;");
//createthecommandforthefunction
OracleCommandcmd=newOracleCommand();
cmd.Connection=conn;
cmd.CommandText="GET_EMPLOYEE_EMAIL";
cmd.CommandType=CommandType.StoredProcedure;
//addtheparameters,includingthereturnparametertoretrieve
//thereturnvalue
cmd.Parameters.Add("p_employee_id",OracleType.Number).Value=101;
cmd.Parameters.Add("p_email",OracleType.VarChar,25).Direction=
ParameterDirection.ReturnValue;
//executethefunction
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
//outputtheresult
Console.WriteLine("Emailaddressis:"+cmd.Parameters["p_email"].Value);
  把持台输入显现了员工101的电子邮件地点。
Emailaddressis:NKOCHHAR
  了局集与REFCURSOR
  可以使用REFCURSOR数据范例来处置Oracle了局集。REFCURSOR是一个指向PL/SQL查询所前往的了局集的指针。与一般的游标分歧,REFCURSOR是一个变量,它是对游标的援用,能够在实行时将其设置为指向分歧的了局集。利用REFCURSOR输入参数能够将Oracle布局化程序的了局集传送回挪用使用程序。经由过程在挪用使用程序中界说OracleType.Cursor数据范例的输入参数,能够会见REFCURSOR所指向的了局集。在利用REFCURSOR的过程当中,OracleConnection必需坚持翻开形态。
  包
  PL/SQL和T-SQL中的存储历程之间的一个严重差别是PL/SQL所利用的Oracle包布局。在T-SQL中没有等效元素。包是在逻辑上相干的编程块(如存储历程和函数)的容器。它包括两个部分:
  •标准:界说包的称号,并为包中的每一个存储历程或函数供应办法署名(原型)。标准头还界说一切全局声明。标准的款式相似于C或C++头文件。

  •注释:包括包头中界说的存储历程和函数的代码。
  每一个存储历程或函数的参数都呈现在括号内,而且用逗号分开。每一个参数还依据必要用以下三个标识符中的一个举行标志:
  •IN:该值从挪用使用程序传送到PL/SQL块。假如未指定标识符,则IN为默许传送偏向。

  •OUT:该值由存储历程天生,并传送回挪用使用程序。

  •INOUT:该值被传送到PL/SQL块,大概在该块外部举行修正,然后前往到挪用使用程序。
  每一个参数也都被标志以唆使数据范例。
  以下包标准界说了四个历程,它们在HR架构的LOCATIONS表中创立、检索、更新和删除数据。
CREATEORnewPACKAGECRUD_LOCATIONSAS
TYPET_CURSORISREFCURSOR;
PROCEDUREGetLocations(cur_LocationsOUTT_CURSOR);
PROCEDUREUpdateLocations(p_location_idINNUMBER,
p_street_addressINVARCHAR2,
p_postal_codeINVARCHAR2,
p_cityINVARCHAR2,
p_state_provinceINVARCHAR2,
p_country_idINCHAR);
PROCEDUREDeleteLocations(p_location_idINNUMBER);
PROCEDUREInsertLocations(p_location_idOUTNUMBER,
p_street_addressINVARCHAR2,
p_postal_codeINVARCHAR2,
p_cityINVARCHAR2,
p_state_provinceINVARCHAR2,
p_country_idINCHAR);
ENDCRUD_LOCATIONS;
  以下代码摘自上述包标准的包注释,申明了GetLocations包中的第一个历程的完成细节:
CREATEORnewPACKAGEBODYCRUD_LOCATIONSAS
PROCEDUREGetLocations(cur_LocationsOUTT_CURSOR)
IS
BEGIN
OPENcur_LocationsFOR
SELECT*FROMLOCATIONS;
ENDGetLocations;
--Implementationofotherproceduresommitted.
ENDCRUD_LOCATIONS;
  利用DataReader
  能够经由过程挪用OracleCommand工具的ExecuteReader()办法来创立OracleDataReader。本节申明怎样利用DataReader来会见由存储历程SELECT_JOB_HISTORY前往的了局集。以下为包标准:
CREATEORnewPACKAGESELECT_JOB_HISTORYAS
TYPET_CURSORISREFCURSOR;
PROCEDUREGetJobHistoryByEmployeeId
(
p_employee_idINNUMBER,
cur_JobHistoryOUTT_CURSOR
);
ENDSELECT_JOB_HISTORY;
  包注释界说了一个历程,该历程检索指定员工的事情履历的了局集,并将其作为REFCURSOR输入参数前往:
CREATEORnewPACKAGEBODYSELECT_JOB_HISTORYAS
PROCEDUREGetJobHistoryByEmployeeId
(
p_employee_idINNUMBER,
cur_JobHistoryOUTT_CURSOR
)
IS
BEGIN
OPENcur_JobHistoryFOR
SELECT*FROMJOB_HISTORY
WHEREemployee_id=p_employee_id;
ENDGetJobHistoryByEmployeeId;
ENDSELECT_JOB_HISTORY;
  以下代码实行该历程,依据了局集创立DataReader,并将DataReader的内容输入到把持台。
//createconnection
OracleConnectionconn=newOracleConnection("DataSource=oracledb;
UserId=UserID;Password=Password;");
//createthecommandforthestoredprocedure
OracleCommandcmd=newOracleCommand();
cmd.Connection=conn;
cmd.CommandText="SELECT_JOB_HISTORY.GetJobHistoryByEmployeeId";
cmd.CommandType=CommandType.StoredProcedure;
//addtheparametersforthestoredprocedureincludingtheREFCURSOR
//toretrievetheresultset
cmd.Parameters.Add("p_employee_id",OracleType.Number).Value=101;
cmd.Parameters.Add("cur_JobHistory",OracleType.Cursor).Direction=
ParameterDirection.Output;
//opentheconnectionandcreatetheDataReader
conn.Open();
OracleDataReaderdr=cmd.ExecuteReader();
//outputtheresultsandclosetheconnection.
while(dr.Read())
{
for(inti=0;i<dr.FieldCount;i++)
Console.Write(dr.ToString()+";");
Console.WriteLine();
}
conn.Close();
  关于HR架构的默许安装,把持台输入显现了员工101的两个纪录中每一个纪录的字段(用分号分开):
101;9/21/198912:00:00AM;10/27/199312:00:00AM;AC_ACCOUNT;110;
101;10/28/199312:00:00AM;3/15/199712:00:00AM;AC_MGR;110;
  上述代码显现,包中的历程是利用包称号(ELECT_JOB_HISTORY)和历程的称号(在此情形下为GetJobHistoryByEmployeeId)指定的,两者之间用句点分开。
  代码还申明了怎样界说了局集的REFCURSOR参数。请注重,数据范例为OracleType.Cursor,偏向为ParameterDirection.Output。
  还请注重,在会见REFCURSOR中的了局集的全部过程当中,毗连都坚持翻开形态。
  假如包前往多个游标,则DataReader会依照您向参数汇合中增加它们的按次来会见这些游标,而不是依照它们在过程当中呈现的按次来会见。可以使用DataReader的NextResult()办法行进到下一个游标。
  前往单个值的存储历程
  OracleCommand类的ExecuteOracleScalar()办法用于实行将单个值作为OracleType数据范例前往的SQL语句或存储历程。假如命令前往一个了局集,则该办法会前往第一行第一列的值。假如前往了REFCURSOR,而不是前往了REFCURSOR所指向的第一行第一列的值,则该办法会前往一个空援用。OracleCommand类的ExecuteScalar()办法相似于ExecuteOracleScalar()办法,只不外它将值作为.NET框架数据范例前往。
  只管云云,在利用Oracle存储历程时,这两个办法都没有效。Oracle存储历程不克不及将值作为RETURN语句的一部分前往,而只能将其作为OUT参数前往。有关信息,请参阅不前往数据的存储历程一节。同时,除经由过程REFCURSOR输入参数之外,您不克不及前往了局集。下一节将对此举行会商。
  您只能利用RETURN参数检索Oracle函数的前往值(如上一节所述),而不克不及利用ExecuteScalar办法之一举行检索。
  序列
  Oracle利用序列来天生独一编号,而不是利用SQLServer所用的数据范例uniqueidentifier。不管是哪一种情形,次要用处都是为主键列天生一系列独一编号。与uniqueidentifier数据范例分歧,序列是与将其用于主键值的一个或多个表有关的数据库工具。
  Oracle序列是原子工具,而且是分歧的。也就是说,一旦您会见一个序列号,Oracle将在处置下一个哀求之前主动递增下一个编号,从而确保不会呈现反复值。
  可使用CREATESEQUENCE命令创立Oracle序列。该命令所带参数包含增量、肇端值、最年夜值、轮回弛缓存。可以使用NEXTVAL和CURRVAL关头字会见序列值。NEXTVAL前往序列中的下一个编号,而CURRVAL供应对以后值的会见。HR架构中的序列LOCATIONS_SEQ按以下体例界说:
CREATESEQUENCELOCATIONS_SEQ
INCREMENTBY100
STARTWITH1
MAXVALUE9900
MINVALUE1
NOCYCLE
NOCACHE
NOORDER
  年夜多半序列代码是不言自明的。NOCYCLE暗示序列在到达最小值或最年夜值后将不再天生其他值。NOCACHE暗示序列值在被哀求之前不会举行分派;可以使用预分派机制来改良功能。NOORDER暗示在天生编号时,不克不及包管依照哀求编号的按次前往这些编号。
  上面的代码显现了一个存储历程,该历程哀求一个序列值,在向LOCATIONS表中拔出纪录时利用它设置主键值,然后在OUT参数中前往该主键值。
CREATEORnewPROCEDUREADD_LOCATION(
p_location_idOUTNUMBER,
p_street_addressINVARCHAR2,
p_postal_codeINVARCHAR2,
p_cityINVARCHAR2,
p_state_provinceINVARCHAR2,
p_country_idINCHAR
)
AS
BEGIN
INSERTINTOLOCATIONS(
LOCATION_ID,
STREET_ADDRESS,
POSTAL_CODE,
CITY,
STATE_PROVINCE,
COUNTRY_ID)
VALUES(
LOCATIONS_SEQ.NEXTVAL,
p_street_address,
p_postal_code,
p_city,
p_state_province,
p_country_id
);

SELECTLOCATIONS_SEQ.CURRVALINTOp_location_idFROMDUAL;
ENDADD_LOCATION;
  上面的代码挪用该存储历程,以拔出一个纪录并检索前往的序列值。
//createtheconnection
OracleConnectionconn=newOracleConnection("DataSource=oracledb;
UserId=UserID;Password=Password;");
//createthecommandforthestoredprocedure
OracleCommandcmd=newOracleCommand();
cmd.Connection=conn;
cmd.CommandText="ADD_LOCATION";
cmd.CommandType=CommandType.StoredProcedure;
//addtheparametersforthestoredprocedureincludingtheLOCATION_ID
//sequencevaluethatisreturnedintheoutputparameterp_location_id
cmd.Parameters.Add("p_location_id",OracleType.Number).Direction=
ParameterDirection.Output;
cmd.Parameters.Add("p_street_address",OracleType.VarChar).Value=
"123AnyStreet";
cmd.Parameters.Add("p_postal_code",OracleType.VarChar).Value="33040";
cmd.Parameters.Add("p_city",OracleType.VarChar).Value="KeyWest";
cmd.Parameters.Add("p_state_province",OracleType.VarChar).Value="FL";
cmd.Parameters.Add("p_country_id",OracleType.VarChar).Value="US";
//executethecommandtoaddtherecords
OracleStringrowId;
conn.Open();
introwsAffected=cmd.ExecuteOracleNonQuery(outrowId);
conn.Close();
//outputtheresults
Console.WriteLine("Rowsaffected:"+rowsAffected);
Console.WriteLine("LocationID:"+
cmd.Parameters["p_location_id"].Value);
  把持台显现一个纪录被拔出到该表中,同时还拔出了该序列天生的主键值。
Rowsaffected:1
LocationID:3300
  利用DataAdapter添补数据集
  可以使用REFCURSOR经由过程DataAdapter来添补DataSet。上面的代码使用了利用DataReader一节中界说的存储历程GetJobHistoryByEmployeeId,并用它在REFCURSOR输入参数中前往的了局集来添补DataSet。
以下是利用DataAdapter添补DataSet的代码:
//createtheconnection
OracleConnectionconn=newOracleConnection("DataSource=oracledb;
UserId=UserID;Password=Password;");
//createthecommandforthestoredprocedure
OracleCommandcmd=newOracleCommand();
cmd.Connection=conn;
cmd.CommandText="SELECT_JOB_HISTORY.GetJobHistoryByEmployeeId";
cmd.CommandType=CommandType.StoredProcedure;
//addtheparametersforthestoredprocedureincludingtheREFCURSOR
//toretrievetheresultset
cmd.Parameters.Add("p_employee_id",OracleType.Number).Value=101;
cmd.Parameters.Add("cur_JobHistory",OracleType.Cursor).Direction=
ParameterDirection.Output;
//createttheDataAdapterfromthecommandanduseittofillthe
//DataSet
OracleDataAdapterda=newOracleDataAdapter(cmd);
DataSetds=newDataSet();
da.Fill(ds);
//outputtheresults.
Console.WriteLine(ds.Tables[0].Rows.Count);
  关于HR架构的默许安装,输入标明员工101有两个JOB_HISTORY纪录。
  利用DataAdapter更新Oracle
  当您利用REFCURSOR参数添补DataSet时,不克不及复杂地利用OracleDataAdapter的Update()办法。这是由于在实行存储历程时,Oracle不克不及供应断定表名和列名所需的信息。要利用DataAdapter的Update()办法,您必需创立在基本表中更新、拔出和删除纪录的历程。该办法相似于在SQLServer中利用的办法。
  本节申明怎样天生一个能够处置所需的创立、检索、更新和删除操纵的包,以便可以从Oracle数据库中检索LOCATION数据,也可以将对DataSet数据所做的不一连变动从头更新到Oracle数据库。包头以下所示:
CREATEORnewPACKAGECRUD_LOCATIONSAS
TYPET_CURSORISREFCURSOR;
PROCEDUREGetLocations(cur_LocationsOUTT_CURSOR);
PROCEDUREUpdateLocations(
p_location_idINNUMBER,
p_street_addressINVARCHAR2,
p_postal_codeINVARCHAR2,
p_cityINVARCHAR2,
p_state_provinceINVARCHAR2,
p_country_idINCHAR);
PROCEDUREDeleteLocations(p_location_idINNUMBER);
PROCEDUREInsertLocations(
p_location_idOUTNUMBER,
p_street_addressINVARCHAR2,
p_postal_codeINVARCHAR2,
p_cityINVARCHAR2,
p_state_provinceINVARCHAR2,
p_country_idINCHAR);
ENDCRUD_LOCATIONS;
  包注释以下所示:
CREATEORnewPACKAGEBODYCRUD_LOCATIONSAS
--retrieveallLOCATIONrecords
PROCEDUREGetLocations(cur_LocationsOUTT_CURSOR)
IS
BEGIN
OPENcur_LocationsFOR
SELECT*FROMLOCATIONS;
ENDGetLocations;
--updateaLOCATIONrecord
PROCEDUREUpdateLocations(
p_location_idINNUMBER,
p_street_addressINVARCHAR2,
p_postal_codeINVARCHAR2,
p_cityINVARCHAR2,
p_state_provinceINVARCHAR2,
p_country_idINCHAR)
IS
BEGIN
UPDATELOCATIONS
SET
STREET_ADDRESS=p_street_address,
POSTAL_CODE=p_postal_code,
CITY=p_city,
STATE_PROVINCE=p_state_province,
COUNTRY_ID=p_country_id
WHERE
LOCATION_ID=p_location_id;
ENDUpdateLocations;
--deleteaLOCATIONrecord
PROCEDUREDeleteLocations(p_location_idINNUMBER)
IS
BEGIN
DELETEFROMLOCATIONS
WHERELOCATION_ID=p_location_id;
ENDDeleteLocations;
--insertaLOCATIONrecord
PROCEDUREInsertLocations
(
p_location_idOUTNUMBER,
p_street_addressINVARCHAR2,
p_postal_codeINVARCHAR2,
p_cityINVARCHAR2,
p_state_provinceINVARCHAR2,
p_country_idINCHAR
)
AS
BEGIN
INSERTINTOLOCATIONS(
LOCATION_ID,
STREET_ADDRESS,
POSTAL_CODE,
CITY,
STATE_PROVINCE,
COUNTRY_ID)
VALUES(
LOCATIONS_SEQ.NEXTVAL,
p_street_address,
p_postal_code,
p_city,
p_state_province,
p_country_id
);

SELECTLOCATIONS_SEQ.CURRVALINTOp_location_idFROMDUAL;
ENDInsertLocations;
ENDCRUD_LOCATIONS;
  上面的代码界说了一个DataAdapter,从而利用上述包中界说的历程来创立、检索、更新和删除撑持DataAdapter的数据。DataAdapter既可用来将数据检索到DataSet中,也可用来将对DataSet所做的变动更新到Oracle数据库中。
//definetheconnectionstring
StringconnString="DataSource=oracledb;UserId=UserID;Password=Password;";
//createthedataadapter
OracleDataAdapterda=newOracleDataAdapter();
//definetheselectcommandforthedataadapter
OracleCommandselectCommand=
newOracleCommand("CRUD_LOCATIONS.GetLocations",
newOracleConnection(connString));
selectCommand.CommandType=CommandType.StoredProcedure;
selectCommand.Parameters.Add("cur_Locations",
OracleType.Cursor).Direction=ParameterDirection.Output;
da.SelectCommand=selectCommand;
//definetheudpatecommandforthedataadapter
OracleCommandupdateCommand=
newOracleCommand("CRUD_LOCATIONS.UpdateLocations",
newOracleConnection(connString));
updateCommand.CommandType=CommandType.StoredProcedure;
updateCommand.Parameters.Add("p_location_id",OracleType.Number,4,
"LOCATION_ID");
updateCommand.Parameters.Add("p_street_address",OracleType.VarChar,40,
"STREET_ADDRESS");
updateCommand.Parameters.Add("p_postal_code",OracleType.VarChar,12,
"POSTAL_CODE");
updateCommand.Parameters.Add("p_city",OracleType.VarChar,30,"CITY");
updateCommand.Parameters.Add("p_state_province",OracleType.VarChar,25,
"STATE_PROVINCE");
updateCommand.Parameters.Add("p_country_id",OracleType.Char,2,
"COUNTRY_ID");
da.UpdateCommand=updateCommand;
//definethedeletecommandforthedataadapter
OracleCommanddeleteCommand=
newOracleCommand("CRUD_LOCATIONS.DeleteLocations",
newOracleConnection(connString));
deleteCommand.CommandType=CommandType.StoredProcedure;
deleteCommand.Parameters.Add("p_location_id",OracleType.Number,4,
"LOCATION_ID");
da.DeleteCommand=deleteCommand;
OracleCommandinsertCommand=
newOracleCommand("CRUD_LOCATIONS.InsertLocations",
newOracleConnection(connString));
insertCommand.CommandType=CommandType.StoredProcedure;
insertCommand.Parameters.Add("p_location_id",OracleType.Number,4,
"LOCATION_ID");
insertCommand.Parameters.Add("p_street_address",OracleType.VarChar,40,
"STREET_ADDRESS");
insertCommand.Parameters.Add("p_postal_code",OracleType.VarChar,12,
"POSTAL_CODE");
insertCommand.Parameters.Add("p_city",OracleType.VarChar,30,"CITY");
insertCommand.Parameters.Add("p_state_province",OracleType.VarChar,25,
"STATE_PROVINCE");
insertCommand.Parameters.Add("p_country_id",OracleType.Char,2,
"COUNTRY_ID");
da.InsertCommand=insertCommand;
//defineaDataTableandfillitusingthedataadapter
DataTabledt=newDataTable();
da.Fill(dt);
//...doworkthatadds,edits,updates,ordeletesrecordsinthetable
//calltheUpdate()methodofthedataadaptertoupdatetheOracle
//databasewithchangesmadetothedata
da.Update(dt);
  利用多个了局集
  Oracle不撑持批量查询,因而没法从一个命令前往多个了局集。利用存储历程时,前往多个了局集相似于前往单个了局集;必需利用REFCURSOR输入参数。要前往多个了局集,请利用多个REFCURSOR输入参数。
  以下是前往两个了局集(全体EMPLOYEES和JOBS纪录)的包标准:
CREATEORnewPACKAGESELECT_EMPLOYEES_JOBSAS
TYPET_CURSORISREFCURSOR;
PROCEDUREGetEmployeesAndJobs(
cur_EmployeesOUTT_CURSOR,
cur_JobsOUTT_CURSOR
);
ENDSELECT_EMPLOYEES_JOBS;
  包注释以下所示:
CREATEORnewPACKAGEBODYSELECT_EMPLOYEES_JOBSAS
PROCEDUREGetEmployeesAndJobs
(
cur_EmployeesOUTT_CURSOR,
cur_JobsOUTT_CURSOR
)
IS
BEGIN
--returnallEMPLOYEESrecords
OPENcur_EmployeesFOR
SELECT*FROMEmployees;
--returnallJOBSrecords
OPENcur_JobsFOR
SELECT*FROMJobs;
ENDGetEmployeesAndJobs;
ENDSELECT_EMPLOYEES_JOBS;
  以下代码显现了怎样利用从上述包中前往的两个了局集来添补DataSet中的两个相干表:
//createtheconnection
OracleConnectionconn=newOracleConnection("DataSource=oracledb;
UserId=UserID;Password=Password;");
//definethecommandforthestoredprocedure
OracleCommandcmd=newOracleCommand();
cmd.Connection=conn;
cmd.CommandText="SELECT_EMPLOYEES_JOBS.GetEmployeesAndJobs";
//addtheparametersincludingthetwoREFCURSORtypestoretrieve
//thetworesultsets
cmd.Parameters.Add("cur_Employees",OracleType.Cursor).Direction=
ParameterDirection.Output;
cmd.Parameters.Add("cur_Jobs",OracleType.Cursor).Direction=
ParameterDirection.Output;
cmd.CommandType=CommandType.StoredProcedure;
//createtheDataAdapterandmaptables
OracleDataAdapterda=newOracleDataAdapter(cmd);
da.TableMappings.Add("Table","EMPLOYEES");
da.TableMappings.Add("Table1","JOBS");
//createandfilltheDataSet
DataSetds=newDataSet();
da.Fill(ds);
//createarelation
ds.Relations.Add("EMPLOYEES_JOBS_RELATION",
ds.Tables["JOBS"].Columns["JOB_ID"],
ds.Tables["EMPLOYEES"].Columns["JOB_ID"]);
//outputthesecondemployee(zero-basedarray)andjobtitle
//basedontherelation
Console.WriteLine("EmployeeID:"+
ds.Tables["EMPLOYEES"].Rows[1]["EMPLOYEE_ID"]+
";JobTitle:"+
ds.Tables["EMPLOYEES"].Rows[1].GetParentRow(
"EMPLOYEES_JOBS_RELATION")["JOB_TITLE"]);
  把持台输入显现了第二个员工的职务:
EmployeeID:101;JobTitle:AdministrationVicePresident
  小结
  经由过程Oracle.NET数据供应程序,能够便利地实行存储历程和会见前往值(不管前往值是一个仍是多个标量值或了局集)。能够将Oracle历程与OracleDataAdapter分离利用,从而添补DataSet、处置不一连的数据和今后将变动更新到Oracle数据库。
  Oracle历程与MicrosoftSQLServer存储历程之间的次要区分是:Oracle历程必需将值作为输入参数前往,而且必需利用输入参数将了局集作为REFCURSOR工具前往给挪用程序。
C#中有两处地方用到new关键字,第一处也是最常见的一处是用在调用构造函数的时候,这种情况也是大家见的最多的一种。另一处是用在派生类中,作用有隐藏成员,切断继承关系等,相信第二处的用法大家明显要比第一处生疏。
小妖女 该用户已被删除
沙发
发表于 2015-1-19 17:45:07 | 只看该作者
现在主流的网站开发语言无外乎asp、php、asp.net、jsp等。
简单生活 该用户已被删除
板凳
发表于 2015-1-27 05:05:16 | 只看该作者
但是java靠开源打出的一片天地,特别是在微软的垄断下能打开今天的局面还是有它的生命力的。
柔情似水 该用户已被删除
地板
发表于 2015-2-4 23:30:39 | 只看该作者
ASP.net的服务器,要求安装一个.net环境,当然我这里指的是windows系统,顺便点一下,.net只能放在windows环境里来运行。Asp.net1.1的就装Framework1.1,Asp.net2.0的就装Framework2.0。
只想知道 该用户已被删除
5#
发表于 2015-3-1 17:08:30 | 只看该作者
在asp.net虚拟主机的服务提供商中,目前首推的是CNNIC的其中一家域名注册机构---时代互联(www.now.net.cn),他们早在2001年微软刚推出Asp.net时就推出了对应的Asp.net虚拟主机了,经笔者的使用测试,他提供的Asp.net性能非常的稳定,版本也会定期的更新,目前他的
再现理想 该用户已被删除
6#
发表于 2015-3-10 21:22:27 | 只看该作者
碰到复杂点的问题都不知道能不能解决,现在有点实力的公司都选择自已在开源的基础上做开发。但没听说过有人在IIS上做改进的,windows、sqlserver集群方面的应用也很少见。
山那边是海 该用户已被删除
7#
发表于 2015-3-17 10:47:17 | 只看该作者
目前在微软的.net战略中新推出的ASP.net借鉴了Java技术的优点,使用CSharp(C#)语言作为ASP.net的推荐语言,同时改进了以前ASP的安全性差等缺点。但是,使用ASP/ASP.net仍有一定的局限性,因为从某种角度来说它们只能在微软的WindowsNT/2000/XP+IIS的服务器平台上良好运行(虽然像ChilliSoft提供了在UNIX/Linux上运行ASP的解决方案.
第二个灵魂 该用户已被删除
8#
发表于 2015-3-24 07:44:58 | 只看该作者
但是java靠开源打出的一片天地,特别是在微软的垄断下能打开今天的局面还是有它的生命力的。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-5-22 21:12

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表