PL / SQL - Oracle:从各个表

时间:2017-06-15 15:53:52

标签: c# oracle entity-framework stored-procedures plsql

我需要什么: 在Oracle DB上的PLS / SQL中,使用参数创建存储过程或函数,这些参数给定声明的表,其中是表的ROW(包含所有字段),返回结果集,遵循参数中给出的条件。之后,我需要使用edmx文件从Microsoft Entity Framework中调用它们。

基本上需要能够将表​​格内容的快速报告提供到pdf中,将一些过滤器与oracle db相匹配。

如果我提供了一个脚本,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我得到:

  

TYPE SCHEMA.THETABLEIWANT

的编译错误      

错误:PLS-00329:架构级别类型具有非法引用   SCHEMA.THETABLEIWANT

mantainer将启动脚本创建我需要的表行的TYPE,然后该函数应该返回一个包含记录的表。

然后从实体框架中调用它应该能够执行它,就像我从我的表调用正常选择,IE:

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

问题在于,mantainers应该能够生成任何内部选择的新报告,而无需我干预软件代码。

任何提示?

也可以将所有选择结果批量放入临时表中,但是当列将发生变化时,它必须是动态的

1 个答案:

答案 0 :(得分:0)

我最终编写了一个PLS / SQL过程,该过程返回一个游标并使用Oracle.ManagedDataAccess Library从C#代码管理它。

这是程序,适合任何感兴趣的人:

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
    }