2017-03-08 45 views
0

我正在寻找一种方法来更新一般的行类型,以便我可以为不同的表插入相同的数据组。动态更新通用行?

我的要求是采取具有非常相似的列像下面的表格。

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); 

从那里我想创建一个通用的解决方案,将更新与三个相同的列有(用户名,用户id,生日)rowtypes。想象一个解决方案和用例看起来如下所示。

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来说可能吗?

回答

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%的时间我建议不要使用这些选项中的任何一个。当表,行和列是“哑”(即关系)时,Oracle工作得最好。使模式程序聪明。不要创建通用对象,而要创建可修改简单表的动态代码。