0

我们有几个基于 Delphi 和 Oracle PL/SQL 存储过程的遗留应用程序。其中一些过程将 PL/SQL 记录作为参数,例如:

create or replace package pck_search is

  type SearchParamsRecType is record(
    search_id       pls_integer,
    search_database pls_integer,
    search_mode     pls_integer,
    result_mode     pls_integer,
    wild_card       pls_integer);

  procedure PerformQuickSearch(p_cursor    in out sys_refcursor,
                               p_parameter in SearchParamsRecType);

end pck_search;

我们现在想要添加一个基于 Web 的客户端 (ASP.Net MVC4),但是我们遇到了这种存储过程的一些问题。当我尝试在 Visual Studio 2012 中使用服务器资源管理器导入存储过程时,我收到以下错误消息:

The function 'PCK_SEARCH.PERFORMQUICKSEARCH' has a parameter 
'P_PARAMETER' at parameter index 0 that has a data type 'pl/sql record' 
which is currently not supported for the target .NET Framework version. 
The function was excluded.  

谷歌搜索错误消息只返回了2010 年的一次点击- 当时的答案是“这是不可能的”。

所以,我的问题归结为:

  • 是否可以使用实体框架导入以记录类型作为参数的 Oracle PL/SQL 存储过程?
  • 实体框架是否有任何替代方案可以处理这种存储过程?
4

2 回答 2

0

You have to distinguish between "PL/SQL Records", "PL/SQL RowTypes" and "SQL Object Types".

Records and Rowtypes are Oracle-specifics and only accessable from PL/SQL - so they're out of scope for EF, which uses basicly SQL.

That's why you'd have to use object types (or "user-defined types" as Oracle calls them).

Here is an extensive piece of documentation about Oracle User-Defined Types (UDTs) and .NET Custom Types

于 2013-06-04T15:17:39.273 回答
0

请仅在没有其他可用的情况下考虑此答案。我还不是 MVC 方面的专家,所以我不能在那里提供建议,但是在 Oracle 端,您可以通过使用接受 MVC 理解的数据类型的包装程序来使 MVC 易于接受。

请注意,我现在无法测试 a CREATE PACKAGE,因此以下内容来自记忆。我不会保证语法,但希望总体思路是显而易见的。

CREATE OR REPLACE PACKAGE pck_wrap_search IS

  PROCEDURE PerformQuickSearch(
    p_cursor in out sys_refcursor,
    -- If MVC doesn't like pls_integer you could make these NUMBER values
    search_id       pls_integer,
    search_database pls_integer,
    search_mode     pls_integer,
    result_mode     pls_integer,
    wild_card       pls_integer);
  END PerformQuickSearch;

END pck_wrap_search;

CREATE OR REPLACE PACKAGE BODY pck_wrap_search IS

  PROCEDURE PerformQuickSearch(
    p_cursor in out sys_refcursor,
    search_id       pls_integer,
    search_database pls_integer,
    search_mode     pls_integer,
    result_mode     pls_integer,
    wild_card       pls_integer)
  IS
    -- I'm not sure if you need to initialize this somehow.
    searchParams pck_search.SearchParamsRecType;
  BEGIN
    -- Assemble the type that the "real" proc needs
    searchParams.search_id       := search_id;
    searchParams.search_database := search_database;
    searchParams.search_mode     := search_mode;
    searchParams.result_mode     := result_mode;
    searchParams.wild_card       := wild_card;
    -- Call the "real" proc
    pck_search.PerformQuickSearch(p_cursor, searchParams);
  END PerformQuickSearch;

END pck_wrap_search;

使用这种方法,您的 MVC 将pck_wrap_search.PerformQuickSearch使用“简单”数据类型调用包装器,并且包装器将“简单”类型放入 Oracle 类型并调用“真实”函数。它不漂亮,也不是灵丹妙药,但它应该可以工作,并且不需要弄乱现有的包。

于 2013-06-04T13:30:46.237 回答