填充模式级表,并将其与 join 一起使用

问题描述 投票:0回答:1

我有一个架构级记录类型和一个架构级表类型,我想用记录填充此表。

create or replace Type t_SLRekord As Object(OWNER VARCHAR2(128),  
                                            TABLE_NAME VARCHAR2(128));

create or replace Type t_SLTable Is Table of t_SLRekord;

我知道这不起作用,因为记录“字段”无法通过这种方式访问:

Declare
    my_SLTable t_SLTable := t_SLTable();
Begin 
    Select Owner, Table_Name
    Bulk Collect Into my_SLTable
    From ALL_TABLES
    Where Owner='OW1' And Table_Name Like 'TN_KO%';
End;

我应该有一个循环,从那里我调用一个填充表格的过程,如下所示:

my_SLTable.EXTEND(1);
my_SLTable(my_SLTable.Count).OWNER := rec(i).OWNER;
my_SLTable(my_SLTable.Count).TABLE_NAME := rec(i).TABLE_NAME;

后来我想与这个模式级表进行联接。我怎样才能做到这一点?

Select t.column_value.Table_Name, at.Owner, at.Table_Name
    Bulk Collect Into v_AT_Table -- just an other PL/SQL coollection
    From ALL_TABLES at, table(my_SLTable) t
    Right Join table(my_SLTable) t on t.column_value.Table_Name = at.Table_Name -- How can I build this join?
        And Owner = 'OW3';

对“虚构”代码感到抱歉。确切的代码会很长。我的目标是找到哪个 Oracle 表丢失了。

sql oracle plsql
1个回答
0
投票

如果您想查找

OW3
模式中与
OW1
模式相比缺失的表,那么您可以使用单个查询,不需要使用 PL/SQL 或对象或集合类型。

SELECT Table_Name
FROM   ALL_TABLES
WHERE  table_name LIKE 'TN_KO%'
GROUP BY table_name
HAVING COUNT(CASE owner WHEN 'OW1' THEN 1 END) > 0
AND    COUNT(CASE owner WHEN 'OW3' THEN 1 END) = 0;

但是,要解决类型问题,如果您有对象类型和集合类型:

CREATE TYPE t_SLRekord AS OBJECT(
  OWNER      VARCHAR2(128),  
  TABLE_NAME VARCHAR2(128)
);

CREATE TYPE t_SLTable IS TABLE OF t_SLRekord;

和表格:

CREATE TABLE tn_ko_1 (id NUMBER);
CREATE TABLE tn_ko_2 (id NUMBER);

然后,简化您的代码以在单个模式上工作(您可以根据需要将其扩展回比较多个模式)。然后,如果您将对象类型收集到集合中(而不是尝试将多个列放入集合中),它将起作用。

DECLARE
  my_SLTable t_SLTable;
  v_AT_Table t_SLTable;
BEGIN
  SELECT t_SLRekord(Owner, Table_Name)
  BULK COLLECT INTO my_SLTable
  FROM   ALL_TABLES
  WHERE  Owner = USER -- 'OW1'
  AND    Table_Name Like 'TN_KO%';

  SELECT t_SLRekord(at.Owner, at.Table_Name)
  BULK COLLECT INTO v_AT_Table -- just an other PL/SQL coollection
  FROM   ALL_TABLES at
         RIGHT OUTER JOIN table(my_SLTable) t
         ON t.Table_Name = at.Table_Name
            AND at.owner = USER -- 'OW3'
         ;

  FOR i IN 1 .. v_at_table.COUNT LOOP
    DBMS_OUTPUT.PUT_LINE(v_at_table(i).owner || '.' || v_at_table(i).table_name);
  END LOOP;
END;
/

哪个输出:

FIDDLE_CICKSCRCWLKQACAKYEBH.TN_KO_1
FIDDLE_CICKSCRCWLKQACAKYEBH.TN_KO_2

小提琴

© www.soinside.com 2019 - 2024. All rights reserved.