【问题标题】:Is it possible to pass objects to PL SQL package procedure as parameters?是否可以将对象作为参数传递给 PL SQL 包过程?
【发布时间】:2012-08-29 11:36:38
【问题描述】:

让我们以 .NET MVC 中的示例为例,其中可以使用自定义对象或什至此类对象数组的参数来定义 ActionResult

方法:

public ActionResult Blah(Person[] people) {
  // ...
}

及对应的HTML:

<input type="text" name="people[0].FirstName" value="George" />
<input type="text" name="people[0].LastName" value="Washington" />
<input type="text" name="people[1].FirstName" value="Abraham" />
<input type="text" name="people[1].LastName" value="Lincoln" />
<input type="text" name="people[3].FirstName" value="Thomas" />
<input type="text" name="people[3].LastName" value="Jefferson" />

示例取自blog

我想知道是否可以在 PL SQL 中做类似的事情,比如:

PROCEDURE blah(param1 IN Person_type)
IS
BEGIN
  -- do whatever y like
END;

其中 person_type 定义对象、记录或类似的复杂结构。

【问题讨论】:

    标签: oracle post plsql


    【解决方案1】:
    CREATE OR REPLACE TYPE t_parsed_name as object (
    name_prefix varchar2(50),
    name_first varchar2(50),
    name_middle varchar2(50),
    name_last varchar2(100),
    name_suffix varchar2(50)
    );
    
    CREATE OR REPLACE TYPE T_PARSED_NAME_ARY as table of t_parsed_name;
    
    create or replace procedure test_parsed_names(i_parsed_name_ary in t_parsed_name_ary) as
        idx pls_integer;
    begin
        idx := i_parsed_name_ary.first;
        loop
            exit when idx is null;
            dbms_output.put_line('First name: ' || i_parsed_name_ary(idx).name_first || ', Last name: ' || i_parsed_name_ary(idx).name_last);
            idx := i_parsed_name_ary.next(idx);
        end loop;
    end;
    
    ----------------------------------------
    -- example using above procedure
    declare
        l_parsed_name t_parsed_name;
        l_parsed_name_ary t_parsed_name_ary;
    begin
      l_parsed_name_ary := t_parsed_name_ary();
      l_parsed_name_ary.extend(3);
    
      -- create some parsed names and add to array
      l_parsed_name := t_parsed_name('Mr','Joe','T','Blow','Jr');
      l_parsed_name_ary(1) := l_parsed_name;
      l_parsed_name := t_parsed_name('Mrs','Jane','','Doe','');
      l_parsed_name_ary(2) := l_parsed_name;
      l_parsed_name := t_parsed_name('','Betty','','Boop','');
      l_parsed_name_ary(3) := l_parsed_name;
    
      -- test the array (call procedure with object type array parameter)
      test_parsed_names(l_parsed_name_ary);
    end;
    

    【讨论】:

    • 对应的 HTML 看起来如何?
    • 当你有一些 HTML 表单中的输入字段,比如&lt;form method="post" action="/test_package.save"&gt;&lt;input type="text" name="person_name" maxlength="200"/&gt;...&lt;/form&gt;,有可能在 save 过程中接收输入字段 'person_name' 的值,如下所示:PROCEDURE save (person_name IN varchar2, position IN varchar2) IS BEGIN --code goes here; END;。我想知道是否有可能以某种方式将 HTML 表单中的值发布到您编写的对象中。我希望,我说清楚了。
    • @ULazdins 所以你的问题是如何从 pl/sql 解析 HTML?如果你想解析 XML,没问题。让您的程序接受 html 文本有点奇怪(imo)。通常接受 get/post 是在应用层完成的。
    • 抱歉,我是 PL SQL 的新手,我来自 .NET (MVC)。我想我忘了提到这段代码在 Web 服务器上运行并返回一个网页。无论如何,谢谢,我不想再用问题来打扰你了,因为我自己无法理解我正在使用的环境,因此我无法提出正确的问题。
    • 是的,我只是喜欢,我们使用带有 mod_plsql 的 Apache Web 服务器
    【解决方案2】:

    可以,但是您需要使用 ODP 和 Oracle 的 UDT(用户定义类型)。不是 100% 确定如何将这些映射到 MVC 位,但您可以将对象类型传递到/从 .net 到 Oracle。

    查看以下链接: Calling a function with user defined type parameters (Oracle ODP.NET) (特别注意这个演练http://st-curriculum.oracle.com/obe/db/hol08/dotnet/udt/udt_otn.htm

    http://docs.oracle.com/html/E15167_01/featUDTs.htm

    您可能需要进行一些微调才能使所有内容同步,但这是可能的。

    【讨论】:

    • 可能但很痛苦。一个更好的问题是使用对象类型可以获得什么:效率,更少的代码?
    • 我实际上在过去对使用对象进行了一些与效率相关的测试。在逐行的基础上,没有效率增益。但是,一旦您开始增加带宽并执行 > 5 条记录(发送集合和执行批量绑定等),UDT 方式对于 CRUDS 来说明显更快。大约 3 次是收支平衡,任何超过 3 次的操作都获得了增量性能。但是,如果您不执行数以万计的操作,与必要的额外编码(维护等)相比,您可能不会实现任何效率提升。
    • 如果我的问题听起来有问题,我很抱歉。结果与 .NET 没有任何关系,我仅将其用作说明。目标是从 POST 接收多个 HTML 字段到一个变量中,我现在来看看答案,看看它是否适合我。
    • @kevinsky 我的目标是最小化代码并使其更易于更改。如果对象 Person 的属性发生更改,我希望此更改对其余代码的影响尽可能小
    • @ULazdins 我相信 UDT 可以完全满足您的需求。有一个学习曲线,但我真的很喜欢他们
    猜你喜欢
    • 2011-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-07
    • 1970-01-01
    • 1970-01-01
    • 2010-12-07
    相关资源
    最近更新 更多