知识大全 ADO.NET访问Oracle 9i存储过程(下)
Posted 序列
篇首语:如果终止了学习,人就结束了成长的进步。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 ADO.NET访问Oracle 9i存储过程(下)相关的知识,希望对你有一定的参考价值。
ADO.NET访问Oracle 9i存储过程(下) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
对于 HR 架构的默认安装 控制台输出显示了员工 的两个记录中每个记录的字段(用分号分隔)
; / / : : AM; / / : : AM;AC_ACCOUNT; ;
; / / : : AM; / / : : AM;AC_MGR; ;
上述代码显示 包中的过程是使用包名称 (ELECT_JOB_HISTORY) 和过程的名称(在此情况下为 GetJobHistoryByEmployeeId)指定的 二者之间用句点分隔
代码还说明了如何定义结果集的 REF CURSOR 参数 请注意 数据类型为 OracleType Cursor 方向为 ParameterDirection Output
还请注意 在访问 REF CURSOR 中的结果集的整个过程中 连接都保持打开状态
如果包返回多个游标 则 DataReader 会按照您向参数集合中添加它们的顺序来访问这些游标 而不是按照它们在过程中出现的顺序来访问 可使用 DataReader 的 NextResult() 方法前进到下一个游标
返回单个值的存储过程
OracleCommand 类的 ExecuteOracleScalar() 方法用于执行将单个值作为 OracleType 数据类型返回的 SQL 语句或存储过程 如果命令返回一个结果集 则该方法会返回第一行第一列的值 如果返回了 REF CURSOR 而不是返回了 REF CURSOR 所指向的第一行第一列的值 则该方法会返回一个空引用 OracleCommand 类的 ExecuteScalar() 方法类似于 ExecuteOracleScalar() 方法 只不过它将值作为 NET框架数据类型返回
尽管如此 在使用 Oracle 存储过程时 这两个方法都没有用 Oracle 存储过程不能将值作为 RETURN 语句的一部分返回 而只能将其作为 OUT 参数返回 有关信息 请参阅不返回数据的存储过程一节 同时 除了通过 REF CURSOR 输出参数以外 您不能返回结果集 下一节将对此进行讨论
您只能使用 RETURN 参数检索 Oracle 函数的返回值(如上一节所述) 而不能使用 ExecuteScalar 方法之一进行检索
序列
Oracle 使用序列 来生成唯一编号 而不是使用 SQL Server 所用的数据类型 uniqueidentifier 无论是哪种情况 主要用途都是为主键列生成一系列唯一编号 与 uniqueidentifier 数据类型不同 序列是与将其用于主键值的一个或多个表无关的数据库对象
Oracle 序列是原子对象 并且是一致的 也就是说 一旦您访问一个序列号 Oracle 将在处理下一个请求之前自动递增下一个编号 从而确保不会出现重复值
可以使用 CREATE SEQUENCE 命令创建 Oracle 序列 该命令所带参数包括增量 起始值 最大值 循环和缓存 可使用 NEXTVAL 和 CURRVAL 关键字访问序列值 NEXTVAL 返回序列中的下一个编号 而 CURRVAL 提供对当前值的访问 HR 架构中的序列 LOCATIONS_SEQ 按如下方式定义
CREATE SEQUENCE LOCATIONS_SEQ
INCREMENT BY
START WITH
MAXVALUE
MINVALUE
NOCYCLE
NOCACHE
NOORDER
大多数序列代码是不言自明的 NOCYCLE 表示序列在达到最小值或最大值后将不再生成其他值 NOCACHE 表示序列值在被请求之前不会进行分配 可使用预分配机制来改善性能 NOORDER 表示在生成编号时 不能保证按照请求编号的顺序返回这些编号
下面的代码显示了一个存储过程 该过程请求一个序列值 在向 LOCATIONS 表中插入记录时使用它设置主键值 然后在 OUT 参数中返回该主键值
CREATE OR new PROCEDURE ADD_LOCATION (
p_location_id OUT NUMBER
p_street_address IN VARCHAR
p_postal_code IN VARCHAR
p_city IN VARCHAR
p_state_province IN VARCHAR
p_country_id IN CHAR
)
AS
BEGIN
INSERT INTO LOCATIONS (
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
);
SELECT LOCATIONS_SEQ CURRVAL INTO p_location_id FROM DUAL;
END ADD_LOCATION;
下面的代码调用该存储过程 以插入一个记录并检索返回的序列值
// create the connection
OracleConnection conn = new OracleConnection( Data Source=oracledb;
User Id=UserID;Password=Password; );
// create the mand for the stored procedure
OracleCommand cmd = new OracleCommand();
cmd Connection = conn;
cmd CommandText = ADD_LOCATION ;
cmd CommandType = CommandType StoredProcedure;
// add the parameters for the stored procedure including the LOCATION_ID
// sequence value that is returned in the output parameter p_location_id
cmd Parameters Add( p_location_id OracleType Number) Direction =
ParameterDirection Output;
cmd Parameters Add( p_street_address OracleType VarChar) Value =
Any Street ;
cmd Parameters Add( p_postal_code OracleType VarChar) Value = ;
cmd Parameters Add( p_city OracleType VarChar) Value = Key West ;
cmd Parameters Add( p_state_province OracleType VarChar) Value = FL ;
cmd Parameters Add( p_country_id OracleType VarChar) Value = US ;
// execute the mand to add the records
OracleString rowId;
conn Open();
int rowsAffected = cmd ExecuteOracleNonQuery(out rowId);
conn Close();
// output the results
Console WriteLine( Rows affected: + rowsAffected);
Console WriteLine( Location ID: +
cmd Parameters[ p_location_id ] Value);
控制台显示一个记录被插入到该表中 同时还插入了该序列生成的主键值
Rows affected:
Location ID:
使用 DataAdapter 填充数据集
可使用 REF CURSOR 通过 DataAdapter 来填充 DataSet 下面的代码利用了使用 DataReader 一节中定义的存储过程 GetJobHistoryByEmployeeId 并用它在 REF CURSOR 输出参数中返回的结果集来填充 DataSet
以下是使用 DataAdapter 填充 DataSet 的代码
// create the connection
OracleConnection conn = new OracleConnection( Data Source=oracledb;
User Id=UserID;Password=Password; );
// create the mand for the stored procedure
OracleCommand cmd = new OracleCommand();
cmd Connection = conn;
cmd CommandText = SELECT_JOB_HISTORY GetJobHistoryByEmployeeId ;
cmd CommandType = CommandType StoredProcedure;
// add the parameters for the stored procedure including the REF CURSOR
// to retrieve the result set
cmd Parameters Add( p_employee_id OracleType Number) Value = ;
cmd Parameters Add( cur_JobHistory OracleType Cursor) Direction =
ParameterDirection Output;
// createt the DataAdapter from the mand and use it to fill the
// DataSet
OracleDataAdapter da = new OracleDataAdapter(cmd);
DataSet ds = new DataSet();
da Fill(ds);
// output the results
Console WriteLine(ds Tables[ ] Rows Count);
对于 HR 架构的默认安装 输出表明员工 有两个 JOB_HISTORY 记录
使用 DataAdapter 更新 Oracle
当您使用 REF CURSOR 参数填充 DataSet 时 不能简单地使用 OracleDataAdapter 的 Update() 方法 这是因为在执行存储过程时 Oracle 不能提供确定表名和列名所需的信息 要使用 DataAdapter 的 Update() 方法 您必须创建在基础表中更新 插入和删除记录的过程 该方法类似于在 SQL Server 中使用的方法
本节说明如何生成一个可以处理所需的创建 检索 更新和删除操作的包 以便能够从 Oracle 数据库中检索 LOCATION 数据 也能够将对 DataSet 数据所做的不连续更改重新更新到 Oracle 数据库 包头如下所示
CREATE OR new PACKAGE CRUD_LOCATIONS AS
TYPE T_CURSOR IS REF CURSOR;
PROCEDURE GetLocations (cur_Locations OUT T_CURSOR);
PROCEDURE UpdateLocations (
p_location_id IN NUMBER
p_street_address IN VARCHAR
p_postal_code IN VARCHAR
p_city IN VARCHAR
p_state_province IN VARCHAR
p_country_id IN CHAR);
PROCEDURE DeleteLocations (p_location_id IN NUMBER);
PROCEDURE InsertLocations (
p_location_id OUT NUMBER
p_street_address IN VARCHAR
p_postal_code IN VARCHAR
p_city IN VARCHAR
p_state_province IN VARCHAR
p_country_id IN CHAR);
END CRUD_LOCATIONS;
包正文如下所示
CREATE OR new PACKAGE BODY CRUD_LOCATIONS AS
retrieve all LOCATION records
PROCEDURE GetLocations (cur_Locations OUT T_CURSOR)
IS
BEGIN
OPEN cur_Locations FOR
SELECT * FROM LOCATIONS;
END GetLocations;
update a LOCATION record
PROCEDURE UpdateLocations (
p_location_id IN NUMBER
p_street_address IN VARCHAR
p_postal_code IN VARCHAR
p_city IN VARCHAR
p_state_province IN VARCHAR
p_country_id IN CHAR)
IS
BEGIN
UPDATE LOCATIONS
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;
END UpdateLocations;
delete a LOCATION record
PROCEDURE DeleteLocations (p_location_id IN NUMBER)
IS
BEGIN
DELETE FROM LOCATIONS
WHERE LOCATION_ID = p_location_id;
END DeleteLocations;
insert a LOCATION record
PROCEDURE InsertLocations
(
p_location_id OUT NUMBER
p_street_address IN VARCHAR
p_postal_code IN VARCHAR
p_city IN VARCHAR
p_state_province IN VARCHAR
p_country_id IN CHAR
)
AS
BEGIN
INSERT INTO LOCATIONS (
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
);
SELECT LOCATIONS_SEQ CURRVAL INTO p_location_id FROM DUAL;
END InsertLocations;
END CRUD_LOCATIONS;
下面的代码定义了一个 DataAdapter 从而使用上述包中定义的过程来创建 检索 更新和删除支持 DataAdapter 的数据 DataAdapter 既可用来将数据检索到 DataSet 中 也可用来将对 DataSet 所做的更改更新到 Oracle 数据库中
// define the connection string
String connString = Data Source=oracledb;User Id=UserID;Password=Password; ;
// create the data adapter
OracleDataAdapter da = new OracleDataAdapter();
// define the select mand for the data adapter
OracleCommand selectCommand =
new OracleCommand( CRUD_LOCATIONS GetLocations
new OracleConnection(connString));
selectCommand CommandType = CommandType StoredProcedure;
selectCommand Parameters Add( cur_Locations
OracleType Cursor) Direction = ParameterDirection Output;
da SelectCommand = selectCommand;
// define the udpate mand for the data adapter
OracleCommand updateCommand =
new OracleCommand( CRUD_LOCATIONS UpdateLocations
new OracleConnection(connString));
updateCommand CommandType = CommandType StoredProcedure;
updateCommand Parameters Add( p_location_id OracleType Number
LOCATION_ID );
updateCommand Parameters Add( p_street_address OracleType VarChar
STREET_ADDRESS );
updateCommand Parameters Add( p_postal_code OracleType VarChar
POSTAL_CODE );
updateCommand Parameters Add( p_city OracleType VarChar CITY );
updateCommand Parameters Add( p_state_province OracleType VarChar
STATE_PROVINCE );
updateCommand Parameters Add( p_country_id OracleType Char
COUNTRY_ID );
da UpdateCommand = updateCommand;
// define the delete mand for the data adapter
OracleCommand deleteCommand =
new OracleCommand( CRUD_LOCATIONS DeleteLocations
new OracleConnection(connString));
deleteCommand CommandType = CommandType StoredProcedure;
deleteCommand Parameters Add( p_location_id OracleType Number
LOCATION_ID );
da DeleteCommand = deleteCommand;
OracleCommand insertCommand =
new OracleCommand( CRUD_LOCATIONS InsertLocations
new OracleConnection(connString));
insertCommand CommandType = CommandType StoredProcedure;
insertCommand Parameters Add( p_location_id OracleType Number
LOCATION_ID );
insertCommand Parameters Add( p_street_address OracleType VarChar
STREET_ADDRESS );
insertCommand Parameters Add( p_postal_code OracleType VarChar
POSTAL_CODE );
insertCommand Parameters Add( p_city OracleType VarChar CITY );
insertCommand Parameters Add( p_state_province OracleType VarChar
STATE_PROVINCE );
insertCommand Parameters Add( p_country_id OracleType Char
COUNTRY_ID );
da InsertCommand = insertCommand;
// define a DataTable and fill it using the data adapter
DataTable dt = new DataTable();
da Fill(dt);
// do work that adds edits updates or deletes records in the table
// call the Update() method of the data adapter to update the Oracle
// database with changes made to the data
da Update(dt);
使用多个结果集
Oracle 不支持批量查询 因此无法从一个命令返回多个结果集 使用存储过程时 返回多个结果集类似于返回单个结果集 必须使用 REF CURSOR 输出参数 要返回多个结果集 请使用多个 REF CURSOR 输出参数
以下是返回两个结果集(全部 EMPLOYEES 和 JOBS 记录)的包规范
CREATE OR new PACKAGE SELECT_EMPLOYEES_JOBS AS
TYPE T_CURSOR IS REF CURSOR;
PROCEDURE GetEmployeesAndJobs (
cur_Employees OUT T_CURSOR
cur_Jobs OUT T_CURSOR
);
END SELECT_EMPLOYEES_JOBS;
包正文如下所示
CREATE OR new PACKAGE BODY SELECT_EMPLOYEES_JOBS AS
PROCEDURE GetEmployeesAndJobs
(
cur_Employees OUT T_CURSOR
cur_Jobs OUT T_CURSOR
)
IS
BEGIN
return all EMPLOYEES records
OPEN cur_Employees FOR
SELECT * FROM Employees;
return all JOBS records
OPEN cur_Jobs FOR
SELECT * FROM Jobs;
END GetEmployeesAndJobs;
END SELECT_EMPLOYEES_JOBS;
以下代码显示了如何使用从上述包中返回的两个结果集来填充 DataSet 中的两个相关表
// create the connection
OracleConnection conn = new OracleConnection( Data Source=oracledb;
User Id=UserID;Password=Password; );
// define the mand for the stored procedure
OracleCommand cmd = new OracleCommand();
cmd Connection = conn;
cmd CommandText = SELECT_EMPLOYEES_JOBS GetEmployeesAndJobs ;
// add the parameters including the o REF CURSOR types to retrieve
// the o result sets
cmd Parameters Add( cur_Employees OracleType Cursor) Direction =
ParameterDirection Output;
cmd Parameters Add( cur_Jobs OracleType Cursor) Direction =
ParameterDirection Output;
cmd CommandType = CommandType StoredProcedure;
// create the DataAdapter and map tables
OracleDataAdapter da = new OracleDataAdapter(cmd);
da TableMappings Add( Table EMPLOYEES );
da TableMappings Add( Table JOBS );
// create and fill the DataSet
DataSet ds = new DataSet();
da Fill(ds);
// create a relation
ds Relations Add( EMPLOYEES_JOBS_RELATION
ds Tables[ JOBS ] Columns[ JOB_ID ]
ds Tables[ EMPLOYEES ] Columns[ JOB_ID ]);
// output the second employee (zero based array) and job title
// based on the relation
Console WriteLine( Employee ID: +
ds Tables[ EMPLOYEES ] Rows[ ][ EMPLOYEE_ID ] +
; Job Title: +
ds Tables[ EMPLOYEES ] Rows[ ] GetParentRow(
EMPLOYEES_JOBS_RELATION )[ JOB_TITLE ]);
控制台输出显示了第二个员工的职务
Employee ID: ; Job Title: Administration Vice President
小结
通过 Oracle NET 数据提供程序 可以方便地执行存储过程以及访问返回值(无论返回值是一个还是多个标量值或结果集) 可以将 Oracle 过程与 OracleDataAdapter 结合使用 从而填充 DataSet 处理不连续的数据以及以后将更改更新到 Oracle 数据库
cha138/Article/program/net/201311/11377相关参考
知识大全 ADO.NET访问Oracle 9i存储过程(上)[1]
ADO.NET访问Oracle9i存储过程(上)[1] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧
知识大全 ADO.NET访问Oracle 9i存储过程(上)[4]
ADO.NET访问Oracle9i存储过程(上)[4] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧
知识大全 ADO.NET访问Oracle 9i存储过程(上)[8]
ADO.NET访问Oracle9i存储过程(上)[8] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧
知识大全 ADO.NET访问Oracle 9i存储过程(上)[5]
ADO.NET访问Oracle9i存储过程(上)[5] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧
知识大全 ADO.NET访问Oracle 9i存储过程(上)[6]
ADO.NET访问Oracle9i存储过程(上)[6] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧
知识大全 ADO.NET访问Oracle 9i存储过程(上)[7]
ADO.NET访问Oracle9i存储过程(上)[7] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧
知识大全 ADO.NET访问Oracle 9i存储过程(上)[2]
ADO.NET访问Oracle9i存储过程(上)[2] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧
知识大全 ADO.NET访问Oracle 9i存储过程(上)[3]
ADO.NET访问Oracle9i存储过程(上)[3] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧
使用ADO.NET访问Oracle9i存储过程 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 本
执行oracle存储过程如下: OracleConnectioncon=newOracleConnection(strcon); &