2017-06-15 73 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 
    }