乐趣区

关于oracle:EditionBased-Redefinition

Oracle 在 11g 引入了 Edition-Based Redefinition(EBR),次要是为了解决在更新数据库对象,比方 PL/SQL 程序,视图等,如果该对象被锁住了,会导致更新必须期待,如果要使更新立刻实现,则须要进行利用的问题。实现形式就是通过创立版本,新的代码在子版本实现,通过指定版本来对新旧版本代码进行切换。

这个性能次要用在有大量 PL/SQL 程序的数据库,例如 Oracle EBS 数据库。

EBR 通过版本化的形式可实现以下指标:

  • 代码的扭转,包含 PL/SQL,表定义等,装置在子(新)版本中
  • 数据的扭转只写到新的表或新的列,父(老)版本不会看到
  • 跨版本触发器将父(老)版本利用所做扭转反映到子(新)版本中,反之亦然

EBR 依赖于 3 类新的对象,即 edition、editioning view 和 crossedition trigger。

  • 若只扭转视图,同义词和 PL/SQL 对象,edition 就够了
  • 若表构造和数据的扭转并是在后端实现,不波及终端用户,则只需 edition 和 editioning view
  • 若表构造和数据的扭转是由终端用户发动,则三者都须要

Edition

版本化和非版本化对象

Edition 是非 Schema 对象,不属于任何用户,从 11gR2 开始,每个数据库都有一个默认版本,即 ORA$BASE。

SQL> show edition  

EDITION
------------------------------
ORA$BASE

SQL> SELECT SYS_CONTEXT('userenv', 'current_edition_name') from dual;

SYS_CONTEXT('USERENV','CURRENT_EDITION_NAME')
--------------------------------------------------------------------------------
ORA$BASE

SQL> select edition_name,parent_edition_name,usable from dba_editions;

EDITION_NAME                   PARENT_EDITION_NAME            USA
------------------------------ ------------------------------ ---
ORA$BASE                                                      YES

可版本化对象

不是所有的模式对象都是可版本化(editionable)的,可版本化的模式对象有:

  • SYNONYM
  • VIEW
  • All PL/SQL object types:

    • FUNCTION
    • LIBRARY
    • PACKAGE and PACKAGE BODY
    • PROCEDURE
    • TRIGGER
    • TYPE and TYPE BODY

除此之外,其余对象,例如表,私有同义词,都是不反对版本化的。

如果可版本化对象的所有者是editions-enabled ,则该对象是editioned ,否则该对象是potentially editioned

版本化对象规定

  • A noneditioned object cannot depend on an editioned object.

    For example:

    • A public synonym cannot refer to an editioned object.
    • A function-based index cannot depend on an editioned function.
    • A materialized view cannot depend on an editioned view.
    • A table cannot have a column of a user-defined data type (collection or Abstract Data Type (ADT)) whose owner is editions-enabled.
    • A noneditioned subprogram cannot have a static reference to a subprogram whose owner is editions-enabled.

For the reason for this rule, see “Actualizing Referenced Objects”.

  • An ADT cannot be both editioned and evolved.

    For information about type evolution, see Oracle Database Object-Relational Developer’s Guide.

  • An editioned object cannot be the starting or ending point of a FOREIGN KEY constraint.

    The only editioned object that this rule affects is an editioned view. An editioned view can be either an ordinary view or an editioning view.

用户启用版本

能够在 CREATE USER 或者 ALTER USER 语句中应用应用 ENABLE EDITIONS 语句来为用户启用版本。该操作是不可逆的,一旦为用户启用版本,则该用户现有可版本化对象及后续创立的可版本化对象就主动版本化了。

如果启用版本的两个用户之间存在相干的依赖关系,还须要应用 FORCE 关键字先为某一个用户启用版本。例如用户 A 有可版本化的对象 a1 和 a2,用户 B 有可版本的对象 b1 和 b2,对象 a1 依赖对象 b1,对象 b2 依赖对象 a2,则为用户 A 和用户 B 启用版本步骤如下:

  1. Using FORCE, enable editions for user A:

    ALTER USER A ENABLE EDITIONS FORCE;

    Now a1 and a2 are editioned objects, and b2 (which depends on a2) is invalid.

  2. Enable editions for user B:

    ALTER USER B ENABLE EDITIONS;
  3. Recompile b2, using the appropriate ALTER statement with COMPILE. For a PL/SQL object, also specify REUSE SETTINGS.

    For example, if b2 is a procedure, use this statement:

    ALTER PROCEDURE b2 COMPILE REUSE SETTINGS

创立版本

应用 CREATE EDITION 语句来创立版本。

继承对象和理论对象

每个数据库会话一次只能应用一个版本。创立时,子版本从其父版本继承数据库中在父版本中可见的所有已版本化对象。每个 继承的对象 在子版本中可见。

例子:creates a procedure named hello in the edition ora$base, and then creates the edition e2 as a child of ora$base. When e2 invokes hello, it invokes the inherited procedure. Then e2 changes hello, actualizing it. The procedure hello in the edition ora$base remains unchanged, and is no longer visible in e2. Now when e2 invokes hello, it invokes the actual procedure.

先创立用户,授予权限,启用版本,切换到新创建的用户

SQL> create user user1 identified by user1 default tablespace users;

User created.

SQL> grant dba to user1;

Grant succeeded.

SQL> alter user user1 enable editions;

User altered.

SQL> conn user1/user1
Connected.

再执行如下步骤:

  1. Create procedure in parent edition:

    CREATE OR REPLACE PROCEDURE hello IS
      BEGIN
        DBMS_OUTPUT.PUT_LINE('Hello, edition 1.');
      END hello;
    /
  2. Invoke procedure in parent edition:

    BEGIN hello(); END;
    /

    Result:

    Hello, edition 1.
     
    PL/SQL procedure successfully completed.
  3. Create child edition:

    CREATE EDITION e2;
  4. Use child edition:

    ALTER SESSION SET EDITION = e2;

    For information about ALTER SESSION SET EDITION, see “Changing Your Session Edition”.

  5. In child edition, invoke procedure:

    BEGIN hello(); END;
    /

    Child edition inherits procedure from parent edition. Child edition invokes inherited procedure. Result:

    Hello, edition 1.
     
    PL/SQL procedure successfully completed.
  6. Change procedure in child edition:

    CREATE OR REPLACE PROCEDURE hello IS
      BEGIN
        DBMS_OUTPUT.PUT_LINE('Hello, edition 2.');
      END hello;
    /

    Child changes only its own copy of procedure. Child’s copy is an actual object.

  7. Invoke procedure:

    BEGIN hello(); END;
    /

    Child invokes its own copy, the actual procedure:

    Hello, edition 2.
    
    PL/SQL procedure successfully completed.
  8. Return to parent:

    ALTER SESSION SET EDITION = ora$base;
  9. Invoke procedure and see that it has not changed:

    BEGIN hello(); END;
    /

    Result:

    Hello, edition 1.
     
    PL/SQL procedure successfully completed.

删除继承对象

如果子版本的用户删除继承对象,则该对象在子版本中不再可见,但在父版本中依然可见。

例子:creates a procedure named goodbye in the edition ora$base, and then creates edition e2 as a child of ora$base. After e2 drops goodbye, it can no longer invoke it, but ora$base can still invoke it.

先删除之前创立的版本:

SQL> show edition

EDITION
------------------------------
ORA$BASE

SQL> drop edition e2 cascade;

Edition dropped.

再执行以下步骤:

  1. Create procedure in edition ora$base:

    CREATE OR REPLACE PROCEDURE goodbye IS
      BEGIN
        DBMS_OUTPUT.PUT_LINE('Good-bye!');
      END goodbye;
    /
  2. Invoke procedure:

    BEGIN goodbye; END;
    /

    Result:

    Good-bye!
     
    PL/SQL procedure successfully completed.
  3. Create edition e2 as a child of ora$base:

    CREATE EDITION e2;
  4. Use edition e2:

    ALTER SESSION SET EDITION = e2;

    ALTER SESSION SET EDITION must be a top-level SQL statement. For more information, see “Changing Your Session Edition”.

  5. In e2, invoke procedure:

    BEGIN goodbye; END;
    /

    e2 invokes inherited procedure:

    Good-bye!
     
    PL/SQL procedure successfully completed.
  6. In e2, drop procedure:

    DROP PROCEDURE goodbye;
  7. In e2, try to invoke dropped procedure:

    BEGIN goodbye; END;
    /

    Result:

    BEGIN goodbye; END;
          *
    ERROR at line 1:
    ORA-06550: line 1, column 7:
    PLS-00201: identifier 'GOODBYE' must be declared
    ORA-06550: line 1, column 7:
    PL/SQL: Statement ignored
  8. Return to parent:

    ALTER SESSION SET EDITION = ora$base;
  9. In parent, invoke procedure:

    BEGIN goodbye; END;
    /

    Result:

    Good-bye!
     
    PL/SQL procedure successfully completed.

例子e2 creates a function named goodbye and then an edition named e3 as a child of e2. When e3 tries to invoke the procedure goodbye (which e2 dropped), an error occurs, but e3 successfully invokes the function goodbye (which e2 created).

  1. Return to e2:

    ALTER SESSION SET EDITION = e2;

    For information about ALTER SESSION SET EDITION, see “Changing Your Session Edition”.

  2. In e2, create function named goodbye:

    CREATE OR REPLACE FUNCTION goodbye
      RETURN BOOLEAN
    IS
    BEGIN
      RETURN(TRUE);
    END goodbye;
    /
  3. Create edition e3:

    CREATE EDITION e3 AS CHILD OF e2;
  4. Use edition e3:

    ALTER SESSION SET EDITION = e3;
  5. In e3, try to invoke procedure goodbye:

    BEGIN
      goodbye;
    END;
    /

    Result:

      goodbye;
      *
    ERROR at line 2:
    ORA-06550: line 2, column 3:
    PLS-00221: 'GOODBYE' is not a procedure or is undefined
    ORA-06550: line 2, column 3:
    PL/SQL: Statement ignored
  6. In e3, invoke function goodbye:

    BEGIN
      IF goodbye THEN
        DBMS_OUTPUT.PUT_LINE('Good-bye!');
      END IF;
    END;
    /

    Result:

    Good-bye!
     
    PL/SQL procedure successfully completed.

版本受权

版本创建者能够应用语句 GRANT USE ON EDITION 将版本的应用权限授予其余用户。

如果要授予所有用户,则能够应用以下两种形式:

  • Grant the USE privilege on the edition to PUBLIC:

    GRANT USE ON EDITION edition_name TO PUBLIC
  • Make the edition the database default edition:

    ALTER DATABASE DEFAULT EDITION = edition_name

    This has the side effect of granting the USE privilege on edition_name to PUBLIC.

以后版本和会话版本

数据库会话在任何工夫应用的版本为以后版本(current edition),当数据库会话开始,以后版本就是其会话版本(session edition),扭转会话版本,以后版本也会随之扭转。然而,也会有以后版本与会话版本不同的状况。

初始会话版本

当连贯数据库时,能够指定初始会话版本,通过以下 SQL 查问能够指定的版本:

SELECT EDITION_NAME FROM ALL_EDITIONS;

那么如何在连贯数据库的时候指定版本呢,能够通过在 service 中指定,Oracle 举荐应用 srvctl add service 或者 srvctl modify service 命令,通过-t 选项指定服务的默认初始会话版本。

如果连贯时没有指定版本,则会应用数据库默认版本作为初始会话版本。

批改会话版本

应用 ALTER SESSION SET EDITION 语句批改以后会话版本。

查看以后版本和会话版本

查看以后版本:

SELECT SYS_CONTEXT('USERENV', 'CURRENT_EDITION_NAME') FROM DUAL;

查看会话版本:

SELECT SYS_CONTEXT('USERENV', 'SESSION_EDITION_NAME') FROM DUAL;

服役版本

通过发出 edition 的 use 权限实现。

删除版本

零碎默认的 edition 不能删除。
必须没有人应用此 edition 时才可删除。
或者其没有子 edition,或者其子 edition 中没有 editioned 对象时才可删除。

Editioning view

因为表是不能被版本化的,那么如果要更改表的构造,如减少字段,这时就须要应用 版本视图 来向用户提供不同版本下的表构造。

Crossedition Triggers

如果公布版本时还波及到数据的变动,那么就须要应用 跨版本触发器。跨版本触发器分为:

  • 正向跨版本触发器:将父版本表字段的数据变动同步到子版本相干字段中,在父版本触发
  • 反向跨版本触发器:将子版本表字段的数据变动同步到父版本相干字段中,在子版本触发

实战

应用 EBR 来进行在线程序更新,具体是将 HR 用户下的 EMPLOYEES 表 PHONE_NUMBER 字段拆分为 COUNTRY_CODE 和 PHONE_NUMBER_WITHIN_COUNTRY 两个字段,这里波及到表构造和数据的变动,须要用到 Editioning view 和 Crossedition Triggers。

筹备工作

  1. 装置数据库
  2. 下载和解压 ebr.zip

配置环境

应用 SYS 用户连贯到数据库:

SQL> conn / as sysdba
Connected.

应用 HR 用户连贯到数据库,默认应用的是父版本 ORA$BASE:

SQL> conn hr/hr
Connected.

SQL> show edition

EDITION
------------------------------
ORA$BASE

EBR 筹备

在 SYS 用户下为 HR 用户启用版本:

SQL> ALTER USER hr ENABLE EDITIONS;

User altered.

在 HR 用户下重命名须要批改的表:

SQL> ALTER TABLE employees RENAME TO employees_;

Table altered.

在 HR 用户下为重命名的表创立版本视图,视图的名字为表之前的名字:

SQL> CREATE EDITIONING VIEW employees AS
  2  SELECT
  3  employee_id, first_name, last_name, email, PHONE_NUMBER, hire_date, job_id, salary, commission_pct, manager_id, department_id
  4  FROM employees_;

View created.

创立子版本

在 SYS 用户下基于以后默认版本 Ora$Base 创立新的版本 post_upgrade:

SQL> CREATE EDITION post_upgrade AS CHILD OF Ora$Base;

Edition created.

应用 SYS 用户将版本 post_upgrade 的 USE 权限授予 HR 用户:

SQL> GRANT USE ON EDITION post_upgrade TO hr;

Grant succeeded.

应用子版本

在 HR 用户下设置以后版本为 post_upgrade:

SQL> ALTER SESSION SET EDITION = post_upgrade;

Session altered.

批改表构造

在 HR 用户下批改 employees_表构造:

SQL> ALTER TABLE employees_ ADD
  2  (COUNTRY_CODE VARCHAR2(5),
  3  PHONE_NUMBER_WITHIN_COUNTRY VARCHAR2(20));

Table altered.

批改版本视图

在 HR 用户下,在子版本 post_upgrade 中,批改之前在父版本 Ora$Base 中创立的版本视图 employees,减少字段 COUNTRY_CODE 和 PHONE_NUMBER_WITHIN_COUNTRY:

SQL> CREATE OR REPLACE EDITIONING VIEW employees AS
  2  SELECT employee_id, first_name, last_name, email, phone_number, hire_date, job_id, salary, commission_pct, manager_id, department_id, phone_number_within_country, country_code
  3  FROM employees_;

View created.

创立正向跨版本触发器

在 HR 用户下,在子版本 post_upgrade 中,执行脚本 fwd_ce.sql,具体代码为:

-- The procedure called by empl_forward
VARIABLE Warnings VARCHAR2(4000)
begin
  :Warnings := $$Plsql_Warnings;
end;
/
--------------------------------------------------------------------------------

alter session set Plsql_Warnings = 'enable:all, disable:06005, disable:06006'
/
create or replace procedure Set_Country_Code_And_Phone_No(
  Phone_Number     in  varchar2, 
  Country_Code     out nocopy varchar2,
  Phone_Number_V2  out nocopy varchar2)
is
  Char_To_Number_Error exception;
  pragma Exception_Init(Char_To_Number_Error, -06502);
  Bad_Phone_Number exception;
  Nmbr varchar2(30) := Replace(Phone_Number, '.', '-');

  function Is_US_Number(Nmbr in varchar2) return boolean is
    Len number := Length(Nmbr);
    Dash_Pos number := Instr(Nmbr, '-');
    n pls_integer;
  begin
    if Len is null or Len <> 12 then
      return false;
    end if;

    if Dash_Pos is null or Dash_Pos <> 4 then return false; end if;
    begin
      n := To_Number(Substr(Nmbr, 1, 3));
    exception when Char_To_Number_Error then
      return false;
    end;

    Dash_Pos := Instr(Nmbr, '-', 5);
    if Dash_Pos is null or Dash_Pos <> 8 then return false; end if;
    begin
      n := To_Number(Substr(Nmbr, 5, 3));
    exception when Char_To_Number_Error then
      return false;
    end;

    begin
      n := To_Number(Substr(Nmbr, 9));
    exception when Char_To_Number_Error then
      return false;
    end;
    return true;
  end Is_US_Number;
begin
  if Nmbr like '011-%' then
    declare
      Dash_Pos number := Instr(Nmbr, '-', 5);
    begin
      Country_Code := '+'||To_Number(Substr(Nmbr, 5, Dash_Pos-5));

      Phone_Number_V2 := Substr(Nmbr, Dash_Pos+1);



    exception when Char_To_Number_Error then
      raise Bad_Phone_Number;
    end;
  elsif Is_US_Number(Nmbr) then
    Country_Code := '+1';
    Phone_Number_V2 := Nmbr;
  else
    raise Bad_Phone_Number;
  end if;
exception when Bad_Phone_Number then
  Country_Code := '+0';
  Phone_Number_V2 := '000-000-0000';
end Set_Country_Code_And_Phone_No;
/

--------------------------------------------------------------------------------
declare
  Stmt constant varchar2(32767) := 'alter session set Plsql_Warnings ='''||:Warnings||'''';
begin
  execute immediate Stmt;
end;
/

-- The trigger empl_forward

CREATE OR REPLACE TRIGGER empl_forward
BEFORE INSERT OR UPDATE ON employees_
FOR EACH ROW
FORWARD CROSSEDITION
DISABLE  
BEGIN
Set_Country_Code_And_Phone_No(
    :New.Phone_Number,
    :New.Country_Code,
    :New.Phone_Number_Within_Country);
END;

这段代码在表 employees_ 创立了一个正向跨版本触发器 empl_forward,当在父版本 Ora$Base 上对表 employees_ 进行 DML 操作时就会触发该触发器,将对父版本的批改传递到子版本去。

SQL> @fwd_ce.sql   

PL/SQL procedure successfully completed.


Session altered.


SP2-0804: Procedure created with compilation warnings


PL/SQL procedure successfully completed.

 12  /

Trigger created.

创立反向扩版本触发器

在 HR 用户下,在子版本 post_upgrade 中,执行脚本 rev_ce.sql,具体代码为:

CREATE OR REPLACE TRIGGER empl_reverse
  BEFORE INSERT OR UPDATE ON employees_
  FOR EACH ROW
  REVERSE CROSSEDITION
  DISABLE
BEGIN
    :NEW.phone_number :=
    CASE :NEW.country_code
      WHEN '+1' THEN
        REPLACE(:NEW.phone_number_within_country, '-', '.')
      ELSE
        '011.'||LTRIM(:NEW.country_code, '+')||'.'||
          REPLACE(:NEW.phone_number_within_country, '-', '.')
    END;
END employees_reverse;
/

这段代码在表 employees_ 创立了一个反向跨版本触发器 empl_reverse,当在子版本 post_upgrade 上对表 employees_ 进行 DML 操作时就会触发该触发器,将对子版本的批改传递到父版本去。

SQL> @rev_ce.sql

Trigger created.

正向操作

在 HR 用户下,在子版本 post_upgrade 中,执行脚本 bulk_fwd.sql,具体代码为:

ALTER trigger empl_forward enable
/
ALTER trigger empl_reverse enable
/
DECLARE
  c number := DBMS_Sql.Open_Cursor();
  x number;
BEGIN
  DBMS_Sql.Parse(
    c                          => c,
    Language_Flag              => DBMS_Sql.Native,
    Statement                  => 'update employees set employee_id = employee_id',
    Apply_Crossedition_Trigger => 'empl_forward');

  x := DBMS_Sql.Execute(c);
  DBMS_Sql.Close_Cursor(c);
  commit;
end;
/

这段代码先启用后面创立的两个触发器,而后执行一个 update 语句,并触发正向跨版本触发器 empl_forward。

SQL> @bulk_fwd.sql

Trigger altered.


Trigger altered.


PL/SQL procedure successfully completed.

执行胜利后,再执行脚本 ver_fwd.sql 查看后果,具体代码为:

-- 切换到父版本,执行 update 会触发正向跨版本触发器
ALTER SESSION SET EDITION =ORA$BASE;
SELECT phone_number FROM employees WHERE employee_id=101;
UPDATE employees SET phone_number = '515.123.4444' WHERE employee_id =101;
COMMIT;

ALTER SESSION SET EDITION = post_upgrade;
SELECT employee_id, country_code, phone_number_within_country 
FROM employees WHERE employee_id =101;

执行后果如下:

SQL> @ver_fwd.sql

Session altered.


PHONE_NUMBER
--------------------
515.123.4568


1 row updated.


Commit complete.


Session altered.


EMPLOYEE_ID COUNT PHONE_NUMBER_WITHIN_
----------- ----- --------------------
        101 +1    515-123-4444

在父版本插入或者更新 employees_表之前,empl_forward 触发器应用 PHONE_NUMBER 字段的新值更新字段 COUNTRY_CODE 和 PHONE_NUMBER_WITHIN_COUNTRY。所以在子版本中,查问 COUNTRY_CODE 和 PHONE_NUMBER_WITHIN_COUNTRY 就能够看到更新的值。

反向操作

在 HR 用户下,在子版本 post_upgrade 中,执行脚本 ver_rev.sql,具体代码为:

-- 在子版本执行 update 会触发反向跨版本触发器
ALTER SESSION SET EDITION =post_upgrade;
UPDATE employees SET phone_number_within_country = '515.123.4567'
WHERE employee_id =101;
SELECT employee_id, country_code, phone_number_within_country
FROM employees WHERE employee_id=101;
COMMIT;

ALTER SESSION SET EDITION = ORA$BASE;
SELECT employee_id, phone_number 
FROM employees WHERE employee_id =101;

执行后果如下:

SQL> @ver_rev.sql

Session altered.


1 row updated.


EMPLOYEE_ID COUNT PHONE_NUMBER_WITHIN_
----------- ----- --------------------
        101 +1    515.123.4567


Commit complete.


Session altered.


EMPLOYEE_ID PHONE_NUMBER
----------- --------------------
        101 515.123.4567

当在子版本 post_upgrade 中向表 employees_插入数据或者更新 PHONE_NUMBER_WITHIN_COUNTRY 字段时,就会触发 empl_reverse 触发器,应用 PHONE_NUMBER_WITHIN_COUNTRY 这个字段的新值来更新 PHONE_NUMBER 字段。

公布版本

通过回收 HR 用户对父版本的权限,来公布子版本。

-- 连贯到 HR 用户,默认应用的还是父版本,查问的数据也是来自于父版本的版本视图
SQL> conn hr/hr
Connected.

SQL> show edition

EDITION
------------------------------
ORA$BASE

SQL> select * from employees where employee_id=101;

EMPLOYEE_ID FIRST_NAME LAST_NAME  EMAIL      PHONE_NUMBER         HIRE_DATE         JOB_ID         SALARY COMMISSION_PCT MANAGER_ID DEPARTMENT_ID
----------- ---------- ---------- ---------- -------------------- ----------------- ---------- ---------- -------------- ---------- -------------
        101 Neena      Kochhar    NKOCHHAR   515.123.4567         20050921 00:00:00 AD_VP           17000                       100            90

-- 连贯到 SYS 用户,设置数据库的默认版本为子版本,而后服役父版本
SQL> conn / as sysdba
Connected.

SQL> ALTER DATABASE DEFAULT EDITION = post_upgrade;

Database altered.

SQL> select grantee,privilege from dba_tab_privs where table_name='ORA$BASE';

GRANTEE                        PRIVILEGE
------------------------------ ----------------------------------------
PUBLIC                         USE

SQL> REVOKE USE ON EDITION ora$base FROM PUBLIC;

Revoke succeeded.

-- 再次连贯到 HR 用户,默认应用的就是子版本了,查问的数据也是来自于子版本的版本视图
SQL> conn hr/hr
Connected.

SQL> show edition

EDITION
------------------------------
POST_UPGRADE

SQL> select * from employees where employee_id=101;

EMPLOYEE_ID FIRST_NAME LAST_NAME  EMAIL      PHONE_NUMBER         HIRE_DATE         JOB_ID         SALARY COMMISSION_PCT MANAGER_ID DEPARTMENT_ID PHONE_NUMBER_WITHIN_ COUNT
----------- ---------- ---------- ---------- -------------------- ----------------- ---------- ---------- -------------- ---------- ------------- -------------------- -----
        101 Neena      Kochhar    NKOCHHAR   515.123.4567         20050921 00:00:00 AD_VP           17000                       100            90 515.123.4567         +1

参考:

  • Edition-based redefinition
  • Performing Online Application Upgrade Using the Edition-Based Redefinition Feature
  • Edition-Based Redefinition 白皮书笔记

欢送关注我的公众号,好好学习,天天向上。

退出移动版