要查看的Oracle 11g联机重新定义表

要查看的Oracle 11g联机重新定义表,oracle,oracle11g,rename,downtime,availability,Oracle,Oracle11g,Rename,Downtime,Availability,这可能是不可能的,但我希望看看是否有一种可行的方法来运行带有视图的表的在线替换 对于分区等在线表重构,DBMS_重新定义非常有效。但我想用(物化的)视图替换表,因此DBMS_的重新定义似乎不合适 在重命名过程中,我没有需要担心的约束、依赖或变化的dml等;我只想在用视图替换表时保持目标的可选性。下面是一个虚构的例子 CREATE TABLE SCI_FI_MOVIE ( SCI_FI_MOVIE_ID NUMBER(10, 0) NOT NULL PRIMARY KEY,

这可能是不可能的,但我希望看看是否有一种可行的方法来运行带有视图的表的在线替换

对于分区等在线表重构,DBMS_重新定义非常有效。但我想用(物化的)视图替换表,因此DBMS_的重新定义似乎不合适

在重命名过程中,我没有需要担心的约束、依赖或变化的dml等;我只想在用视图替换表时保持目标的可选性。下面是一个虚构的例子

  CREATE TABLE SCI_FI_MOVIE (
  SCI_FI_MOVIE_ID NUMBER(10, 0)        NOT NULL PRIMARY KEY,
  NAME            VARCHAR2(100) UNIQUE NOT NULL,
  DIRECTOR        VARCHAR2(100)        NOT NULL,
  REVIEW_SCORE    NUMBER(1, 0) CHECK ( REVIEW_SCORE IN (1, 2, 3, 4, 5))
);

CREATE TABLE NO_SCORES_SCI_FI_MOVIE (
  SCI_FI_MOVIE_ID NUMBER(10, 0)        NOT NULL PRIMARY KEY,
  NAME            VARCHAR2(100) UNIQUE NOT NULL,
  DIRECTOR        VARCHAR2(100)        NOT NULL
);

CREATE MATERIALIZED VIEW KUBRICK_SABOTAGE
(SCI_FI_MOVIE_ID, NAME, DIRECTOR, REVIEW_SCORE)
REFRESH COMPLETE ON COMMIT
AS
  SELECT
    SCI_FI_MOVIE_ID,
    NAME,
    DIRECTOR,
    CASE WHEN DIRECTOR = 'KUBRICK'
      THEN 5
    ELSE 2 END AS REVIEW_SCORE
  FROM NO_SCORES_SCI_FI_MOVIE;

INSERT INTO SCI_FI_MOVIE VALUES (1, 'Apollo 13', 'HOWARD', 5);
INSERT INTO SCI_FI_MOVIE VALUES (2, '2001: A Space Odyssey', 'KUBRICK', 4);

INSERT INTO NO_SCORES_SCI_FI_MOVIE VALUES (1, 'Apollo 13', 'HOWARD');
INSERT INTO NO_SCORES_SCI_FI_MOVIE VALUES (2, '2001: A Space Odyssey', 'KUBRICK');

COMMIT;

-- THEN WHAT STEPS TO REPLACE TABLE WITH VIEW?
在本例中,我希望以名为SCI\u FI\u MOVIE的MV结束,并将表SCI\u FI\u MOVIE重命名为SCI\u FI\u TEMP或任何待删除的内容。如果可以以原子方式进行替换,则在替换原始表之前不需要存在MV

我希望避免对对象名称解析的任何中断或妥协(
CREATE PUBLIC SYNONYM
然后重命名original在这里不起作用)

有没有一种干净的、不停机的方法可以做到这一点?
我可以根据需要自由禁用日志记录、只读等功能;唯一的目标是防止字典切换期间出现“ORA-00942:表或视图不存在”。我使用的是11gR2,但也欢迎使用12c解决方案


非常感谢您的想法

您不需要在线重新定义或进行任何巧妙的操作;您尝试执行的操作是通过以下方式内置的:

ON PREBUILD TABLE子句允许您将现有表注册为预初始化的物化视图。对于在数据仓库环境中注册大型物化视图,此子句特别有用。该表必须与生成的物化视图具有相同的名称并位于相同的架构中

如果删除物化视图,则先前存在的表将恢复为表的标识

所以你可以做:

CREATE MATERIALIZED VIEW SCI_FI_MOVIE
(SCI_FI_MOVIE_ID, NAME, DIRECTOR, REVIEW_SCORE)
ON PREBUILT TABLE
REFRESH COMPLETE ON COMMIT
AS
  SELECT
    SCI_FI_MOVIE_ID,
    NAME,
    DIRECTOR,
    CAST(CASE WHEN DIRECTOR = 'KUBRICK'
      THEN 5
    ELSE 2 END AS NUMBER(1,0)) AS REVIEW_SCORE
  FROM NO_SCORES_SCI_FI_MOVIE;

Materialized view SCI_FI_MOVIE created.
需要转换(…AS NUMBER(1,0))以使生成的数据类型与基础表匹配

在构建MV时,表被锁定(这几乎是即时的,因为没有数据收集或创建),因此在发生这种情况时,对它的查询只会短暂阻塞

该视图将具有原始表值:

select * from SCI_FI_MOVIE;

SCI_FI_MOVIE_ID NAME                           DIRECTOR   REVIEW_SCORE
--------------- ------------------------------ ---------- ------------
              1 Apollo 13                      HOWARD                5
              2 2001: A Space Odyssey          KUBRICK               4
。。。在刷新之前(在本例中)将在下一次提交时:

INSERT INTO NO_SCORES_SCI_FI_MOVIE VALUES (3, 'Star Wars', 'LUCAS');

1 row inserted.

COMMIT;

select * from SCI_FI_MOVIE;

SCI_FI_MOVIE_ID NAME                           DIRECTOR   REVIEW_SCORE
--------------- ------------------------------ ---------- ------------
              1 Apollo 13                      HOWARD                2
              2 2001: A Space Odyssey          KUBRICK               5
              3 Star Wars                      LUCAS                 2

对于普通(非物化视图),只要您可以创建一个公共同义词,就可以进行一些洗牌来实现同样的效果:

CREATE TABLE SCI_FI_MOVIE_TMP_TAB AS SELECT * FROM SCI_FI_MOVIE;

CREATE VIEW SCI_FI_MOVIE_TMP_VIEW AS SELECT * FROM SCI_FI_MOVIE_TMP_TAB;

CREATE PUBLIC SYNONYM SCI_FI_MOVIE FOR SCI_FI_MOVIE_TMP_VIEW;

ALTER TABLE SCI_FI_MOVIE RENAME TO SCI_FI_MOVIE_OLD;

CREATE VIEW SCI_FI_MOVIE AS
  SELECT
    SCI_FI_MOVIE_ID,
    NAME,
    DIRECTOR,
    CAST(CASE WHEN DIRECTOR = 'KUBRICK'
      THEN 5
    ELSE 2 END AS NUMBER(1,0)) AS REVIEW_SCORE
  FROM NO_SCORES_SCI_FI_MOVIE;

DROP PUBLIC SYNONYM SCI_FI_MOVIE;

DROP VIEW SCI_FI_MOVIE_TMP_VIEW;

DROP TABLE SCI_FI_MOVIE_TMP_TAB;

DROP TABLE SCI_FI_MOVIE_OLD;

这有赖于。当您重命名原始表时,它在当前模式(命名空间)中再也找不到具有该名称的对象,并查找公共同义词,并愉快地使用它。当创建的视图再次优先于公共同义词时

@AlexPoole谢谢Alex我现在就编辑。那么你想要你所展示的KUBRICK_破坏,但被称为科幻电影的东西吗?谢谢Alex。是的,我想把MV KUBRICK_Destroyate重新命名为科幻电影,并用SCI_FI_MOVIEExcellent表的重新命名(或删除)。越简单越好。我接受。但是我很好奇,如果这是一个传统的视图而不是MV,会有类似的吗?@alexgibbs-我想你应该重新命名这个表并在它上面创建视图,但是你有一个简短的窗口,它会显示ORA-00942。好的,我会用标准视图记住这一点。Thanks@alexgibbs-添加了一种(可能)使用普通视图执行此操作的方法。您可能没有创建公共同义词的特权;如果从另一个模式访问该表,它仍然会短暂失败,因为
。SCI\u FI\u MOVIE
无法解决表重命名和视图创建之间的问题。感谢后续操作。在最初的问题中,您提到了我所关心的问题,即在一个公共同义词下移动——多个用户使用完全限定的对象名。这将有助于对模式限定同义词与公共同义词进行有趣的实验。