2011-05-27 74 views
4

我在SOF上发现了一些关于如何针对Oracle运行多个查询(BEGIN END块,匿名存储过程)的问题/答案。我想要做的是几乎相同的,但我想这些查询,以填补多个数据表中的“一气呵成”:用1 OracleCommand填充多个数据表

所以不是我们平常:每个数据表一个查询像 (这是“伪码”,而不是一个工作例子!)

Odp.Fill(SomeQuery, SomeDataTable, SomeParameters); 

我想一起做的

Odp.Fill(
    new Query(SomeQuery, SomeDataTable, SomeParameters), 
    new Query(SomeQuery2, SomeDataTable2, SomeParameters), 
    ...) 
+0

为什么要使用一个单一的呼叫,而不是几个那些?是因为易用性,对性能增益的显着期望,原子执行,事务处理,错误处理等? – Codo 2011-05-27 11:06:58

+0

>“期望(显着的)性能增益” 这个新的“BulkFill”方法的实现也将是一个很好的添加点(自定义?即新查询(sql,dt,customErrMsg))错误处理,减少数量的DAL代码,提高填充方法的“可读性”,... – Laoujin 2011-05-27 11:37:32

回答

7

行这只是许多方面,你可以得到在一个查询多个表一个东西。

PL/SQL

CREATE OR REPLACE PACKAGE getBldgRoom AS 

/****************************************************************************** 

    NAME:  getBldgRoom 
    PURPOSE: 

    REVISIONS: 
    Ver  Date  Author   Description 
    --------- ---------- --------------- ------------------------------------ 
    1.0  2011-5-27 has986  1. Created this package. 

******************************************************************************/ 

PROCEDURE getBldgRoom(rcBuildingData OUT SYS_REFCURSOR, rcRoomData OUT SYS_REFCURSOR); 


END getBldgRoom; 

/

CREATE OR REPLACE PACKAGE BODY GETBLDGROOM AS 
PROCEDURE getBldgRoom(rcBuildingData OUT SYS_REFCURSOR, rcRoomData OUT SYS_REFCURSOR) IS 
    BEGIN 
     OPEN rcBuildingData FOR 
       select bldg_code, bldg_desc from IH_CSI_OWNER.BUILDING; 

     OPEN rcRoomData FOR 
       select bldg_code, room_code, room_desc from IH_CSI_OWNER.ROOM; 
    END getBldgRoom; 

END GETBLDGROOM; 

/

C#代码

using System; 
using System.Data; 
using Oracle.DataAccess.Client; //Needs Oracle Data Access Client (ODAC) 

namespace ClassLibrary 
{ 
    public class TwoTableDataSet 
    { 
     public DataSet getTwoTables() 
     { 
      OracleConnection conn = new OracleConnection(); 

      //Normally we get the connection string from the web.config file or the app.config file 
      conn.ConnectionString = "Persist Security Info=False;User Id=*USER_NAME*;Password=*USER_PASSWORD*;Data Source=*DataBaseName*"; 
      DataSet ds = new DataSet(); 

      try 
      { 
       conn.Open(); 

       //------------------------------------------------------------------------------------------------------ 
       //Set up the select command 
       OracleCommand cmd = new OracleCommand(); 
       cmd.BindByName = true; //If you do not bind by name, you must add parameters in the same order as they are listed in the procedure signature. 
       cmd.Connection = conn; 
       cmd.CommandType = CommandType.StoredProcedure; //A procedure in an oracle package 
       cmd.CommandText = "GETBLDGROOM.GetBldgRoom"; //The name of the procedure 

       cmd.Parameters.Add("rcBuildingData", OracleDbType.RefCursor, ParameterDirection.Output); 
       cmd.Parameters.Add("rcRoomData", OracleDbType.RefCursor, ParameterDirection.Output); 

       OracleDataAdapter da = new OracleDataAdapter(); 
       da.SelectCommand = cmd; 

       //------------------------------------------------------------------------------------------------------ 

       //get the data from the two tables in the procedure 
       da.Fill(ds); 
       //ds now contains ds.Tables[0] and ds.Tables[1] 

       //Let's give them names 
       ds.Tables[0].TableName = "BUILDINGS"; 
       ds.Tables[1].TableName = "ROOMS"; 

       //Let's add a relationship between the two tables 
       DataColumn parentColumn = ds.Tables["BUILDINGS"].Columns["BLDG_CODE"]; 
       DataColumn childColumn = ds.Tables["ROOMS"].Columns["BLDG_CODE"]; 
       DataRelation dr = new System.Data.DataRelation("BuildingsRooms", parentColumn, childColumn); 
       ds.Relations.Add(dr); 
      } 
      catch (Exception ex) 
      { 
       //Add a breakpoint here to view the exception 
       //Normally the exception would be written to a log file or EventLog in the case of a Web app 
       //Alternatively, it could be sent to a WebService which logs errors and then it could work for both Web or Windows apps 
       Exception lex = ex; 
      } 
      finally 
      { 
       if (conn.State == ConnectionState.Open) 
       { 
        conn.Close(); 
       } 
      } 

      return ds; 
     } 
    } 
} 

希望这有助于

哈维Sather

+0

完美。这正是我需要解决我的问题。 – Holt 2015-11-05 18:07:31

+0

真的很感谢先生!你的建议帮了我很多! – 2016-03-21 06:01:47