Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 操纵集合_Sql_Oracle_Collections_Plsql - Fatal编程技术网

Sql 操纵集合

Sql 操纵集合,sql,oracle,collections,plsql,Sql,Oracle,Collections,Plsql,我尝试对不同元素(所有者、表)的列表进行排序。 只需一个就很容易(而且非常快!),例如: declare TYPE tbl_list IS TABLE OF VARCHAR2(64); l_tables tbl_list; i number; begin l_tables:=tbl_list(); for i in 1..100000 loop l_tables:= l_tables MULTISET UNION DISTINCT tbl_list('myTable'

我尝试对不同元素(所有者、表)的列表进行排序。 只需一个就很容易(而且非常快!),例如:

declare
TYPE tbl_list IS TABLE OF VARCHAR2(64);
l_tables tbl_list;
i number;
begin
  l_tables:=tbl_list();
  for i in 1..100000
    loop
      l_tables:= l_tables MULTISET UNION DISTINCT tbl_list('myTable');
    end loop;
    for i in l_tables.first..  l_tables.last
      loop
        dbms_output.put_line(l_tables(i));
      end loop;  
end;
/
我试着用同样的方法列出一个列表,但失败了:

create or replace TYPE tbl_list2 IS OBJECT (l_owner  VARCHAR2(64),l_name  VARCHAR2(64));




declare
l_object tbl_list2;
i number;
begin
  l_object:=tbl_list2('','');

  for i in 1..100000
    loop
      l_object:= l_object MULTISET UNION DISTINCT tbl_list2('myOwner','MyTable');
    end loop;
    for i in l_object.first..  l_object.last
      loop
        dbms_output.put_line(l_object(i));
      end loop;  

end;
/
但我明白了以下几点: PLS-00306:调用“MULTISET\u UNION\u DISTINCT”时参数的数量或类型错误。

目标是要有一个所有不同(所有者、表)的列表,当然,我不在乎你是否找到任何其他想法

解决方案当然是两个字中的一个字的串联,但我想找到更优雅的

编辑 @ThinkJet:

我喜欢你的解决方案。它比我肮脏的解决方案更优雅。 但是,你的解决方案比我的慢70倍左右! 那么,我们怎样才能收敛到一个优雅的蚂蚁速度解呢

这是我的脏东西:

declare
TYPE tbl_list IS TABLE OF VARCHAR2(64);
l_tables tbl_list;
i number;
begin
  l_tables:=tbl_list();
  for i in 1..100000
    loop
      l_tables:= l_tables MULTISET UNION DISTINCT tbl_list('myOwner'||','||'myTable');
    end loop;
    for i in l_tables.first..  l_tables.last
      loop
        dbms_output.put_line('OWNER='||REGEXP_SUBSTR(l_tables(i),'[^,]+', 1, 1));
        dbms_output.put_line('TABLE='||REGEXP_SUBSTR(l_tables(i),'[^,]+', 1, 1));
      end loop;  
end;

/至少在第二种情况下,您丢失了一个表定义。本声明:

create or replace TYPE tbl_list2 IS OBJECT (l_owner  VARCHAR2(64),l_name  VARCHAR2(64));
仅声明对象(或记录)类型,而不是表

因此,您需要分两步进行:

create or replace TYPE tbl_list_rec IS OBJECT (l_owner  VARCHAR2(64),l_name  VARCHAR2(64));
/

create or replace TYPE tbl_list2 as table of tbl_list_rec;
/
之后,您需要在脚本中进行一些语法更正:

declare
  l_object tbl_list2;
  i        number;
begin
  -- for list initialization it must be filled with constructed objects
  l_object := tbl_list2( tbl_list_rec('','') );

  for i in 1..100000 loop          

    -- 1. select values to variable
    -- 2. Fix constructor for list 
    select 
      l_object MULTISET UNION DISTINCT tbl_list2(tbl_list_rec('myOwner','MyTable'))
    into 
      l_object 
    from 
      dual;

    end loop;

    for i in l_object.first ..  l_object.last loop
      -- output separate fields, there are now default conversion from 
      -- user-defined objects to varchar2.
      dbms_output.put_line(l_object(i).l_owner || ',' || l_object(i).l_name);
    end loop;  

end;
/
更新 由于大量的上下文切换,上述解决方案相对较慢。但是,如果不做一些额外的工作,就无法在PL/SQL中直接比较复杂的对象类型实例。
为了让Oracle知道对象实例是相同的还是不同的,我们需要定义。这两种方法都是不允许的,因此需要选择合适的方法。MAP方法执行速度更快,在我们的例子中不需要排序,因此请继续:

create or replace TYPE tbl_list_rec2 AS OBJECT (
  l_owner  VARCHAR2(64),
  l_name  VARCHAR2(64),
  map member function get_key return varchar2
);
/
实施:

create or replace TYPE BODY tbl_list_rec2 AS 

  map member function get_key return varchar2
  is
  begin
    return l_owner||chr(1)||l_name;
  end;

end;
/
在这之后,可以测试PL/SQL代码中的对象是否相等,如问题的第一个示例中的simple
varchar2

declare
  l_object tbl_list2a;
  i        number; 
begin
  l_object := tbl_list2a( tbl_list_rec2('','') );

  for i in 1..100000 loop          
    l_object := l_object MULTISET UNION DISTINCT tbl_list2a(tbl_list_rec2('myOwner','MyTable'));
  end loop;

  for i in l_object.first..  l_object.last loop
    dbms_output.put_line(l_object(i).l_owner || ',' || l_object(i).l_name);
  end loop;  

end;
/

SQL>创建或替换类型tbl\U list2作为tbl\U list\U rec的表格;2/创建或替换类型tbl_列表2作为tbl_列表记录表;ORA-06545:PL/SQL:编译错误-编译中止ORA-06550:第0行第0列:PLS-00565:TBL_列表2必须作为潜在参考目标(对象类型)完成您好,感谢您的快速回答。创建tbl_列表记录是可以的,但是使用tbl_列表记录我得到了PLS-00565。请检查您的情况是否。。。简而言之:如果从SQL*Plus执行,请将
/
放在每个类型定义之后。好的,这就是工作。我更新了我的问题以获得更直观的解决方案!我喜欢!脏的更快,但你的眼睛更清晰!谢谢你,好的。只是想确定一下。。。问题中的测试用例是否正确地反映了您的需求?是有很多像示例中那样的小查询,还是相对较少的大数据集部分?是的,这个测试用例大致反映了我的需求请检查更新的答案。。。