繁体   English   中英

如何删除记录并在一条语句中返回它们? SQL / Java

[英]How to delete records and return them in one statement? SQL/Java

我很难解决这个问题。 我知道必须有一种方法可以做到,而且我可能非常接近(也许没有)。 我想从表中删除一组记录,并返回在一个语句中删除的记录。 该表是一个队列,我需要从中弹出一些记录。

这通过2条语句完成工作:

select id, add_date from my_queue where rownum <= 10;
-- save for processing
delete from my_queue where rownum <= 10;

如何将这些合并为1条语句,然后在Java中读取结果?

我看了这个SO问题,并尝试实现该问题中的两种方法,但是,在我的情况下,我有2列要输出,并且我需要使用bulk collect into子句,因此输出将是一个表。 这样,我无法弄清楚正确定义和注册输出以执行匿名PL / SQL语句所需的操作。

这是我最接近的尝试:

StringBuilder sql = new StringBuilder();
sql.append("BEGIN ");
sql.append("  delete from my_queue where rownum <= 10 ");
sql.append("  returning _id into ?; ");
sql.append("END; ");

CallableStatement cstmt = con.prepareCall(sql.toString());
cstmt.registerOutParameter(1, OracleTypes.CURSOR);
//cstmt.registerOutParameter(1, OracleTypes.NUMBER);
//cstmt.registerOutParameter(1, OracleTypes.ARRAY);

cstmt.execute(); // throws error, see comments below

这是基于注册的输出类型执行时的各种错误:

使用CURSOR: ORA-00932: inconsistent datatypes: expected CURSER got NUMBER

使用NUMBER: ORA-01422: exact fetch returns more than requested number of rows

使用阵列: ORA-03115: unsupported network datatype or representation

我结合了来自多个不同帖子/网站的解决方案,并使用大bulk collect into子句提出了一个可行的解决方案:

create or replace type queue_record as object (
  id number(10),
  add_date date
);

create or replace type my_queue_type as table of queue_record;

create or replace procedure pull_from_queue (
  pull_size in number,
  pulled_records out sys_refcursor
)
is
  tbl my_queue_type;
begin

  delete from my_queue
  where id in (
    select id from ( select * from my_queue order by add_date )
    where rownum <= pull_size
  )
  returning queue_record(id, add_date)
  bulk collect into tbl;

  open pulled_records for
  select * from table(cast(tbl as my_queue_type)) order by add_date;

end pull_from_queue;

您可以使用plsql关联数组来存储所选数据,并从表中删除记录。 这是pl / SQL示例。

/* Formatted on 12/20/2016 3:45:29 PM (QP5 v5.277) */
DECLARE
   TYPE type_rec IS RECORD
   (
      Employee_id     NUMBER,
      Employee_name   VARCHAR2 (30)
   );

   TYPE type_aa IS TABLE OF type_rec
      INDEX BY PLS_INTEGER;

   l_var1   type_aa;
BEGIN
   FOR loop_aa IN (SELECT ROWNUM rn, Employee_id, Employee_name
                     FROM employees                
                  )
   LOOP
      l_var1 (loop_aa.rn).Employee_id := loop_aa.Employee_id;
      l_var1 (loop_aa.rn).Employee_name := loop_aa.Employee_name;
      DBMS_OUTPUT.put_line (
            'Employee ID: '
         || loop_aa.Employee_id
         || ', Employee Name: '
         || loop_aa.Employee_name);
   END LOOP loop_aa;

   -- Delete records here
  DELETE FROM employees;
  --Commit;

END;
/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM