Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.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 DML子查询中的嵌套表_Sql_Oracle_Plsql_Oracle12c - Fatal编程技术网

Sql DML子查询中的嵌套表

Sql DML子查询中的嵌套表,sql,oracle,plsql,oracle12c,Sql,Oracle,Plsql,Oracle12c,使用Oracle12cee,如何在DML子查询中使用PL/SQL包类型而不引发异常“ORA-00902:无效数据类型” 示例模式 sqlselect-WORKS中的PL/SQL类型 对于SELECT,从PL/SQL类型到SQL的转换非常有效。以下代码运行良好: declare vt test_pkg.type_table; v_count number; begin select count(*) into v_count from dual wh

使用Oracle12cee,如何在DML子查询中使用PL/SQL包类型而不引发异常“ORA-00902:无效数据类型”

示例模式 sqlselect-WORKS中的PL/SQL类型 对于SELECT,从PL/SQL类型到SQL的转换非常有效。以下代码运行良好:

declare
    vt test_pkg.type_table;
    v_count number;
begin
    select count(*)
    into v_count
    from dual
    where not exists(select column1 from table(vt));
end;
/
SQL更新中的PL/SQL类型-失败 但在DML语句中使用相同的类型和子查询会引发异常:“ORA-00902:无效数据类型/ORA-06512:在第4行”

SQL更新中的SQL类型-WORKS 相比之下,在子查询中使用SQL对象在DML中效果很好:

declare
    vt type_table;
begin
    update tableX set a = 1
    where not exists (select column1 from table(vt));
end;
/

为每个查询创建SQL对象是一种变通方法,但这会创建许多不必要的模式对象。有没有办法让PL/SQL包类型在DML子查询中工作?

我想这是一个意见问题,因为我使用db级别的类型,因为(imho)是保持代码干净的原因。但这只是另一种看待它的方式。然而,你在寻找什么,至少在这种情况下,不是那么困难。您已经在创建使用这些定义的包。您只需将定义移动到包规范中即可。这样就不需要或很少需要更改代码。此外,这些定义仍然可以在包本身之外使用

create or replace package pkg_t1 as  
   type type_record is record(
      column1        number,
      column2        number,
      column3        number);

   type type_table is table of type_record;

   function build_type_records(rows_to_build in integer) 
     return type_table;

   function build_pipe_records(rows_to_build in integer) 
     return type_table 
     pipelined;    

end pkg_t1;
/

create or replace package body pkg_t1 as

   function build_type_records(rows_to_build in integer) 
   return  type_table 
   is  
      v_type type_table := type_table();
   begin 
      for i in 1 .. rows_to_build 
      loop 
         v_type.extend;      
         v_type(i).column1 := trunc(dbms_random.value(1,100)); 
         v_type(i).column2 := trunc(dbms_random.value(100,500));
         v_type(i).column3 := dbms_random.value();
      end loop ;

     return  v_type;
   end build_type_records; 

  function build_pipe_records(rows_to_build in integer) 
    return type_table 
    pipelined 
  is
    v_rec type_table;
  begin
    v_rec:= build_type_records(rows_to_build); 
    for i in 1 .. v_rec.count
    loop
      pipe row (v_rec(i));
    end loop; 
  end build_pipe_records;

end pkg_t1;
/ 

declare 
  tt pkg_t1.type_table; 
  num_of_rows integer := &Number_of_rows;
begin
  tt := pkg_t1.build_type_records( num_of_rows );
  for i in 1 .. tt.count
  loop
      dbms_output.put_line( 'Result: '
                            || 'Column1==>' || tt(i).column1 || ', ' 
                            || 'Column2==>' || tt(i).column2 || ', '
                            || 'Column3==>' || tt(i).column3
                          ) ; 
  end loop; 
end ; 
/

select * from table(pkg_t1.build_pipe_records(&Rows_Desirded));

我想这是一个意见问题,因为我使用db级别类型,因为(imho)是保持代码干净的原因。但这只是另一种看待它的方式。然而,你在寻找什么,至少在这种情况下,不是那么困难。您已经在创建使用这些定义的包。您只需将定义移动到包规范中即可。这样就不需要或很少需要更改代码。此外,这些定义仍然可以在包本身之外使用

create or replace package pkg_t1 as  
   type type_record is record(
      column1        number,
      column2        number,
      column3        number);

   type type_table is table of type_record;

   function build_type_records(rows_to_build in integer) 
     return type_table;

   function build_pipe_records(rows_to_build in integer) 
     return type_table 
     pipelined;    

end pkg_t1;
/

create or replace package body pkg_t1 as

   function build_type_records(rows_to_build in integer) 
   return  type_table 
   is  
      v_type type_table := type_table();
   begin 
      for i in 1 .. rows_to_build 
      loop 
         v_type.extend;      
         v_type(i).column1 := trunc(dbms_random.value(1,100)); 
         v_type(i).column2 := trunc(dbms_random.value(100,500));
         v_type(i).column3 := dbms_random.value();
      end loop ;

     return  v_type;
   end build_type_records; 

  function build_pipe_records(rows_to_build in integer) 
    return type_table 
    pipelined 
  is
    v_rec type_table;
  begin
    v_rec:= build_type_records(rows_to_build); 
    for i in 1 .. v_rec.count
    loop
      pipe row (v_rec(i));
    end loop; 
  end build_pipe_records;

end pkg_t1;
/ 

declare 
  tt pkg_t1.type_table; 
  num_of_rows integer := &Number_of_rows;
begin
  tt := pkg_t1.build_type_records( num_of_rows );
  for i in 1 .. tt.count
  loop
      dbms_output.put_line( 'Result: '
                            || 'Column1==>' || tt(i).column1 || ', ' 
                            || 'Column2==>' || tt(i).column2 || ', '
                            || 'Column3==>' || tt(i).column3
                          ) ; 
  end loop; 
end ; 
/

select * from table(pkg_t1.build_pipe_records(&Rows_Desirded));

“我需要停止在db中使用类型”为什么?不使用SQL类型的驱动因素是什么?公司要求。保持代码干净。“我需要停止在db中使用类型”为什么?不使用SQL类型的驱动因素是什么?公司要求。保持代码整洁。我认为这并不能直接回答问题。(这些想法可能有助于原创海报,但我不认为它们解决了问题根源的怪异行为。)现在的问题是,我同意。但现在已经不是几天前的情况了。这种奇怪的行为在当时甚至现在都不是问题。我认为这并不能直接回答问题。(这些想法可能有助于原创海报,但我不认为它们解决了问题根源的怪异行为。)现在的问题是,我同意。但现在已经不是几天前的情况了。这种奇怪的行为在当时甚至现在都不是问题。
create or replace package pkg_t1 as  
   type type_record is record(
      column1        number,
      column2        number,
      column3        number);

   type type_table is table of type_record;

   function build_type_records(rows_to_build in integer) 
     return type_table;

   function build_pipe_records(rows_to_build in integer) 
     return type_table 
     pipelined;    

end pkg_t1;
/

create or replace package body pkg_t1 as

   function build_type_records(rows_to_build in integer) 
   return  type_table 
   is  
      v_type type_table := type_table();
   begin 
      for i in 1 .. rows_to_build 
      loop 
         v_type.extend;      
         v_type(i).column1 := trunc(dbms_random.value(1,100)); 
         v_type(i).column2 := trunc(dbms_random.value(100,500));
         v_type(i).column3 := dbms_random.value();
      end loop ;

     return  v_type;
   end build_type_records; 

  function build_pipe_records(rows_to_build in integer) 
    return type_table 
    pipelined 
  is
    v_rec type_table;
  begin
    v_rec:= build_type_records(rows_to_build); 
    for i in 1 .. v_rec.count
    loop
      pipe row (v_rec(i));
    end loop; 
  end build_pipe_records;

end pkg_t1;
/ 

declare 
  tt pkg_t1.type_table; 
  num_of_rows integer := &Number_of_rows;
begin
  tt := pkg_t1.build_type_records( num_of_rows );
  for i in 1 .. tt.count
  loop
      dbms_output.put_line( 'Result: '
                            || 'Column1==>' || tt(i).column1 || ', ' 
                            || 'Column2==>' || tt(i).column2 || ', '
                            || 'Column3==>' || tt(i).column3
                          ) ; 
  end loop; 
end ; 
/

select * from table(pkg_t1.build_pipe_records(&Rows_Desirded));