Oracle中的部分对象

时间:2012-03-11 07:46:11

标签: oracle user-defined-types

我在oracle中使用平面存储过程(平面意味着不包含在对象中)来更新我的表。例如,我有一个表Person,其中包含列Id,FirstName,LastName,Address,Salary。我做了一个平坦的过程Person_UpdFirstName,这个过程有两个参数:Id,FirstName。在过程中,我在Person表中找到与参数Id匹配的行,并使用参数FirstName更新FirstName。通常的东西,没什么新鲜的。

现在,我正在使用oracle对象。我有一个对象PersonType,这是一个udt。此对象与表Person中的列具有相同的字段。我已将所有与Person表相关的过程放在PersonType对象中,也就是说,我开始使用成员过程而不是使用flat过程。没有任何成员过程具有任何参数,它们从对象的字段中获取值。例如,在Person_UpdFirstName平面过程的情况下,现在我有一个成员过程UpdFirstName。此成员过程不接受任何参数,它使用对象本身的Id和FirstName字段,并像以前一样更新Person表。

问题是,当我使用平面过程时,我传递的参数如Id,FirstName,所以在一个包含数百个表的大型系统中,我不能错误地将参数传递给存储过程,因为数字和类型每个存储过程中的参数是固定的。现在我正在使用对象,我必须记住要填充的对象的哪些字段,系统中没有内置检查。只要表Person中的字段不可为空,这是好的,因为它会抛出异常,但如果表中的字段可以为空,或者当我比较值时,那么我可能会有很多逻辑错误。

我的问题是,是否有一些内置的方法来关闭这个潜在错误的大门。我有一些粗略的解决方案,但不确定:

  1. 某种偏见的物体。我的成员方法应该被强制接受参数那些部分对象。例如,我有一个部分对象PersonUpdFirstNameType,它只有一个字段FirstName,然后我的UpdFirstName成员方法将此作为参数。当然,为表上的每个操作制作单独的部分类型是很麻烦的。我真的不喜欢这个解决方案
  2. 我不会将对象从c#传递到oracle过程,而是在参数中传递变量,然后根据需要手动构建(或不构建)oracle对象。
  3. 我找到了一种用c#类映射oracle对象的方法。为此,我不必使用任何ORM工具。我只需要在这些类的c#类和c#字段上添加一些属性,并实现一些接口。所以,我实际上可以将c#对象传递给oracle过程并使用“。” oracle过程中的语法,用于访问包含实际数据的字段。

    我认为我问的问题是一般的oop问题,因此它并不特定于任何特定语言。一般问题是假设你有一个C类,其中包括F1,F2,F3,F4,F5和方法M1,M2,M3。 M1在某些字段上执行某些操作,M2在某些其他字段上执行某些操作,M3在某些字段上执行某些操作,这些操作也可能由M1或M2执行。客户端代码正在创建C的对象,并且可以在调用任何方法之前填充任何数量(包括零)的参数。如果客户端代码在将值放入方法所需的字段之前调用方法,该怎么办?在C#中,我认为这是由编译器通过抛出异常来处理的,如果你不首先初始化字段;您也可以在类的定义中将字段留空,例如“int i”,而不在i中添加任何值,以便在调用方法时,编译器会抛出异常。由于可空字段,dbms中没有这样的支持。如果假设您正在将表行的Id与对象字段的Id进行比较,并且您忘记在对象字段中放置任何值,那么将表行的id与null进行比较,并且没有匹配的行,因此不会更新发生(假设您要更新与id匹配的行,通常的更新操作)。

    我只是想知道系统中是否有一些内置的检查来处理这种情况。

1 个答案:

答案 0 :(得分:1)

我不知道如何在编译时间中出现错误,而且我不知道任何其他OO语言也提供这样的功能(编译器如何判断何时或者属性被启动的地方?)
你可以做的是在运行时中有例外(有点像NullPointerExceptionArgumentNullException)。
例如:

create or replace type person_o as object
(
  id    number,
  fname varchar2(32),
  lname varchar2(32),

  member procedure update_lname
);
/

create or replace type body person_o is

  member procedure update_lname is
  begin
    if self.lname is null then
      Raise_application_error(-20000, 'null attribute');
    end if;

    update persons_table set last_name = self.lname where id = self.id;
    commit;
  end;

end;
/