动态更新通用行?

时间:2017-03-08 19:06:41

标签: sql oracle

我正在寻找一种更新行类型的方法,这样我就可以为不同的表插入相同的数据组。

我的要求是采用与下面列相似的列的表。

create table storedNumber(myNumber number, userName varchar2(4000), userId number, birthDate date);
/
create table storedVarchar(myVarchar varchar2(4000), userName varchar2(4000), userId number, birthDate date);

从那里我想创建一个通用解决方案,它将使用那里的三个相同列(userName,userId,birthDate)更新行类型。想象一个解决方案和用例看起来像下面这样。

procedure UpdateRowWithUserInfo(in_tableName varchar2, in_rowType in out generic_row(?), in_userInfo userInfo) is
begin
  in_rowType('userName') := in_userInfo.userName;
  in_rowType('userId') := in_userInfo.userId;
  in_rowType('birthDate') := in_userInfo.birthDate;
end;
/
declare
  l_userInfo   userInfo;
  l_numberRow  storedNumber%rowtype;
  l_varcharRow storedVarchar%rowtype;
begin
  -- This returns a userInfo object from the id with the userName, userId, and birthDate populated
  l_userInfo := get_userInfo(123);

  -- Getting some data for the rows
  l_numberRow.myNumber := 42;
  l_varcharRow.myVarchar := 'Hello World';

  -- This function should update the input row's columns with the input user info
  UpdateRowWithUserInfo('storedNumber', l_numberRow, l_userInfo);
  UpdateRowWithUserInfo('storedVarchar', l_varcharRow, l_userInfo);
end;

使用Oracle会有这样的事吗?

1 个答案:

答案 0 :(得分:0)

这可以使用Oracle的对象关系功能来完成。

create or replace type userInfo is object
(
    userName  varchar2(100),
    userId    number,
    birthDate date
) not final;

create or replace type userInfoWithNumber under userInfo
(
    myNumber number
) not final;

create or replace type userInfoWithVarchar under userInfo
(
    myVarchar2 varchar2(100)
) not final;

create or replace procedure UpdateRowWithUserInfo(targetUserInfo in out userInfo, sourceUserInfo in userinfo) is
begin
    targetUserInfo.userName  := sourceUserInfo.userName;
    targetUserInfo.userId    := sourceUserInfo.userId;
    targetUserInfo.birthDate := sourceUserInfo.birthDate;
end;
/

declare
    l_userInfo   userInfo; 
    l_numberRow  userInfoWithNumber;
    l_varcharRow userInfoWithVarchar;
begin
    l_userInfo   := userInfo('A', 1, date '2000-01-01');
    l_numberRow  := userInfoWithNumber('B', 2, date '2000-01-02', 42);
    l_varcharRow := userInfoWithVarchar('C', 3, date '2000-01-03', 'Hello World');

    UpdateRowWithUserInfo(l_numberRow, l_userInfo);
    UpdateRowWithUserInfo(l_varcharRow, l_userInfo);

    --Print new values to demonstrate that they have changed.
    --Values were originally "B" and "C" but will now be "A".
    dbms_output.put_line(l_numberRow.username);
    dbms_output.put_line(l_varcharRow.username);
end;
/

这不是完全动态的,因为必须在架构上创建对象。可以使用AnyTypes创建更通用的解决方案。

但99%的时间我建议不要使用其中任何一个选项。当表,行和列是" dumb"时,Oracle效果最佳。 (即关系)。使架构程序智能化。而不是创建通用对象,创建可以修改简单表的动态代码。