Oracle:创建免除完全空行的表副本

Oracle: Create a table copy exempting totally null rows

提问人:CDove 提问时间:8/15/2023 更新时间:8/15/2023 访问量:35

问:

我的任务是修复 Oracle 中的一个坏数据问题。有完全空的行(百万),没有PK,没有indeces,并且经常使用该表。这导致消耗型应用程序的速度大幅下降。我的想法是,由于该表也需要备份,因此使用此处描述的功能: 在oracle中创建现有表的完整副本。这将为我提供一张新的表格来创建 PK 和 indeces,并确保所有触发器等结转。然后,我可以使用重命名来交换哪个表是“备份”表,而不是生产表。

我的想法是在创建新表时劫持该子句,并将“WHERE 1 = 0”替换为过滤完全空行的值。但是,完全为 null,我的意思是每个值都是 null。WHERE

CREATE TABLE 'TABLE' AS SELECT * FROM OLD_TABLE WHERE......

有没有比一遍又一遍地将每一列与同一子查询进行比较更快的方法?大约有 60 列。SELECTAND

...WHERE col1 NOT IN (long subquery)
AND col2 NOT IN (identical long subquery)
AND col3 not in....
数据库 Oracle PLSQL RDBMS

评论

0赞 Paul W 8/15/2023
不要使用子查询。只是一个普通的 WHERE 子句......但是您必须以一种或另一种方式列出每一列才能测试它们。
0赞 Paul W 8/15/2023
顺便说一句,您应该考虑使用移动而不是重新定义或 CTAS/重命名。例如 至于组装 60 列列表,只需通过按顺序查询并将它们编写脚本并复制粘贴到记事本编辑器中,然后按照您需要的方式进行调整即可。无需全部输入。ALTER TABLE old_table MOVE INCLUDING ROWS WHERE col1 IS NOT NULL OR col1 IS NOT NULL OR...column_nameall_tab_columnscolumn_id

答:

0赞 rgm565 8/15/2023 #1

这可能就是你要找的:

CREATE TABLE new_table AS
SELECT *
FROM  old_table
WHERE col1 IS NOT NULL
OR    col2 IS NOT NULL
etc
0赞 Littlefoot 8/15/2023 #2

我没有包含那么多行或列的表,所以这只是一个理论,因为我不知道它会如何执行。


如果您不想备份所有列所在的行(顺便说一句,您如何在这样的表中拥有主键?主键不允许 null),为什么需要这么复杂的子句?如果要跳过所有空值,请完全这样做。nullwhere

例如,这是您拥有的“原始”表;请注意所有列均为 null 的最后一行:

    SQL> desc test
     Name                                      Null?    Type
     ----------------------------------------- -------- ----------------------------
     COL1                                               NUMBER
     COL2                                               CHAR(1)
     COL3                                               NUMBER
    
    SQL> select rowid, t.* from test t;
    
    ROWID                    COL1 COL2       COL3
    ------------------ ---------- ---- ----------
    AAAZNlAAMAAAAOLAAA          1 A
    AAAZNlAAMAAAAOLAAB                        100
    AAAZNlAAMAAAAOLAAC                               --> all NULLs here
    

一种选择是使用 function:如果它返回 ,则表示所有列均为 null:coalescenull

SQL> create table test_new as
  2  select *
  3  from test
  4  where coalesce(to_char(col1), col2, to_char(col3)) is not null;

Table created.

SQL> select t.rowid, t.* from test_new t;

ROWID                    COL1 COL2       COL3
------------------ ---------- ---- ----------
AAAZNqAAMAAAAOrAAA          1 A
AAAZNqAAMAAAAOrAAB                        100

另一种选择是逐个指定子句中的所有列:where

SQL> create table test_new_2 as
  2  select *
  3  from test
  4  where col1 is not null
  5     or col2 is not null
  6     or col3 is not null;

Table created.

SQL> select t.rowid, t.* From test_new_2 t;

ROWID                    COL1 COL2       COL3
------------------ ---------- ---- ----------
AAAZNrAAMAAAAOzAAA          1 A
AAAZNrAAMAAAAOzAAB                        100

SQL>

或者,您可以通过 include 子句来使用 Data Pump 导出和导入实用程序来过滤掉包含所有 null 值的行。where

评论

0赞 CDove 8/18/2023
回答您的问题;该表没有 PK,并且使用另一个表对“主”的引用来获取数据。当然,这是一场迟钝的、搞砸的噩梦。它给人的感觉就像有人拿走了MS Access数据,然后把它扔进去。
0赞 Littlefoot 8/18/2023
明白了;那么,你设法做了你需要做的事情吗?