如何循环删除

How to loop over delete

我想知道是否以及如何循环 delete 语句的结果。

delete 语句能够 return 已删除记录的值:

Firebird 2.5 Language Reference

DELETE
  FROM {target} [[AS] alias]
  [WHERE {search-conditions | CURRENT OF cursorname}]
  [PLAN plan_items]
  [ORDER BY sort_items]
  [ROWS <m> [TO <n>]]
  [RETURNING <returning_list> [INTO <variables>]]

<m>, <n>         ::=  Any expression evaluating to an integer.
<returning_list> ::=  ret_value [, ret_value ...]
<variables>      ::=  :varname [, :varname ...]

但是使用 returning 语法,具有多个结果记录的 delete 给我:

multiple rows in singleton select.

像这样的块语句

EXECUTE BLOCK
RETURNS (
  ADSREF TYPE OF DMN_REFID)
AS
begin
  for
    delete from m_s_ad_memo
      returning ADSREF into :adsref
  do
    suspend;
end

returns 以下错误信息:

Invalid token.
Dynamic SQL Error.
SQL error code = -104.
Token unknown - line 7, column 5.
delete.

那么,这可能吗?

它可以与周围的 for select ... do 循环和游标一起使用吗?
这种方法会是什么样子?
我还没有使用过游标。

你不能。

But using the returning syntax, a delete with more than one result record gives me: multiple rows in singleton select.

完全正确。

当使用 RETURNING 子句执行时,

INSERT/UPDATE/DELETE/UPDATE-OR-INSERT 被视为存储过程调用 class 语句,而不是查询 class 语句。

这意味着它们 return 不是许多不同行的一些“结果集”,而是 return 一组标量 Parameters/Fields。

而且您不能“循环”完全不包含任何行的集合。


您 link 的文档声称

RETURNING

A DELETE statement removing at most one row may optionally include a RETURNING clause in order to return values from the deleted row.

重点来自文档本身。

你可以这样做:

CREATE OR ALTER PROCEDURE NEW_PROCEDURE
RETURNS (
    OUT VARCHAR(10))
AS
DECLARE VARIABLE ID INTEGER;
DECLARE VARIABLE TEXT VARCHAR(10);
BEGIN
  FOR SELECT xxx.id
  FROM xxx
  WHERE xxx.id < 5 --some condition
  INTO :ID DO
  BEGIN
    DELETE FROM xxx
    WHERE xxx.id = :ID
    RETURNING xxx.name INTO :TEXT;    /*this is optional (you could select this 
                                        text in up select statement*/

    OUT = :ID || ' ' || :TEXT;

    SUSPEND;
  END
END