我需要什么: 在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应该能够生成任何内部选择的新报告,而无需我干预软件代码。
任何提示?
也可以将所有选择结果批量放入临时表中,但是当列将发生变化时,它必须是动态的
答案 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
}