2017-06-15 22 views
1

我需要的: 在Oracle數據庫的PLS/SQL中,使用參數創建一個存儲過程或函數,該參數給定一個聲明表,其中是ROW一個表(包含所有字段),按照參數中給出的條件返回結果集。之後,我需要使用edmx文件從Microsoft Entity Framework中調用它們。PL/SQL - Oracle:從各種表中返回數據集的存儲過程

基本上需要能夠提供表格內容的快速報告到一個pdf,匹配一些過濾器,與oracle數據庫。

mantainer必須能夠提供我提供的腳本來創建和添加新報告,因此這需要是動態的。

這裏是我到目前爲止有:

CREATE OR REPLACE type THETABLEIWANTTYPE as table of THETABLEIWANT%TYPE 

create function 
    SCHEMA.THETABLEIWANT_FUNCTION(PARAM_GR in number default 1) 
    return THETABLEIWANTTYPE 
    PIPELINED 
    as 
    result_table THETABLEIWANTTYPE 
    begin 
    SELECT S.id, S.idg, S.sta, S.tab 
     Bulk collect into result_table 
     from SCHEMA.THETABLEIWANT S 
     WHERE IDGR = PARAM_GR 

     IF result_table.count > 0 THEN 
     for i in result_table.FIRST .. result_table.LAST loop 
      pipe row (result_table(i)) 
      end loop 
      end if 
      return 
    end; 

但它不工作。它給出了錯誤。

運行CREATE TYPE我得到:

Compilation errors for TYPE SCHEMA.THETABLEIWANT

Error: PLS-00329: schema-level type has illegal reference to SCHEMA.THETABLEIWANT

的mantainer將啓動腳本創建我需要的錶行的類型,那麼函數應該返回與記錄的表。

然後從實體框架調用它,我應該能夠像我從我的表來調用一個正常的選擇來執行它,IE:

``_dbContext.THETABLEIWANT.Where(X => x.IDGR = Param_gr).ToList();

問題是,mantainers應該能夠使用任何內部選擇生成新的報告,而不需要我對軟件代碼的干預。

任何提示?

它的確定也是以散裝所有的選擇結果到一個臨時表,但它必須是動態的列將改變

+0

您的意思是'%ROWTYPE'而不是'%TYPE' ?無論如何,它們都是PL/SQL結構,所以你不能用它們來定義模式級別(即非PL/SQL)類型。它是否必須是流水線函數,或者您是否可以使用引用遊標作爲結果(這可能是弱類型的,這可能本身就是您的調用者的問題)? –

+0

試試這個:'CREATE OR REPLACE type THETABLEIWANTTYPE as object(col1 col1_datatype,col2 col2_datatype'; then'CREATE OR REPLACE type THETABLEIWANTTAB as table of THETABLEIWANTTYPE' – g00dy

回答

0

我最後寫一個返回遊標PLS/SQL程序和管理IT C#代碼與Oracle.ManagedDataAccess庫。

這裏的程序,有興趣的人士:

CREATE OR REPLACE PROCEDURE SCHEMA.PROC_NAME(
PARAM_1 VARCHAR2, 
RESULT OUT SYS_REFCURSOR) 
IS 
BEGIN 
OPEN RESULT FOR 
SELECT A, V, C AS MY_ALIAS from SCHEMA.TABLE WHERE FIELD = PARAM_1 AND FIELD_2 = 'X'; 
END; 

而這裏的C#代碼調用並獲得結果:

OracleConnection conn = new OracleConnection("CONNECTIONSTRING"); 

    try 
     { 
      if (conn.State != ConnectionState.Open) 
       conn.Open(); 

      List<OracleParameter> parametri = new List<OracleParameter>() 
        { 
         new OracleParameter 
         { 
          ParameterName = nameof(filter.PARAM_1), 
          Direction = ParameterDirection.Input, 
          OracleDbType = OracleDbType.NVarchar2, 
          Value = filter.PARAM_1 
         } 
        }; 


      OracleCommand cmd = conn.CreateCommand(); 
      cmd.Parameters.AddRange(parametri.ToArray()); 

      OracleParameter cursor = cmd.Parameters.Add(
       new OracleParameter 
       { 
        ParameterName = "RESULT", 
        Direction = ParameterDirection.Output, 
        OracleDbType = OracleDbType.RefCursor 
       } 
      ); 

      cmd.CommandText = procedureName; 
      cmd.CommandType = CommandType.StoredProcedure; 
      cmd.ExecuteNonQuery(); 
      using (OracleDataReader reader = ((OracleRefCursor)cursor.Value).GetDataReader()) 
      { 
       if (reader.HasRows) 
        while (reader.Read()) 
        { 
         //Iterate the result set 
        } 
      } 
    } 
    catch(Exception ex) 
    { 
     //Manage exception 
    }