2017-08-23 3 views
1

Ich frage mich, ob und wie man das Ergebnis (e) einer delete-Anweisung durchlaufen kann.Wie Schleife über löschen

Die delete Aussage in der Lage, Werte der gelöschten Datensatz zurückzukehren:

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 ...] 

Aber die returning Syntax, ein delete mit mehr als einem Rekordergebnis gibt ich:

mehrere Zeilen in Singleton auswählen.

einer Blockanweisung wie solche

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

gibt folgende Fehlermeldung:

Ungültiger Token.
Dynamischer SQL-Fehler.
SQL-Fehlercode = -104.
Token unbekannt - Zeile 7, Spalte 5.
löschen.

Also, ist das überhaupt möglich?

Könnte es mit einem umgebenden for select ... do -loop und einem Cursor funktionieren?
Wie würde ein solcher Ansatz aussehen?
Ich habe noch nicht mit Cursors gearbeitet.

+1

Zwei Links zu Beispielen von „Arbeit mit Cursor“ sind bei https://stackoverflow.com/a/45373980/976391 - aber Cursor kann sehr langsam sein in FB3, in 3.01, 3.02, .... finden sich noch Performance-Bugs in ihnen. –

Antwort

2

Sie können nicht.

Aber mit der zurückkehrenden Syntax, gibt ein Löschen mit mehr als einem Ergebnissatz mir: mehrere Zeilen in Singleton auswählen.

Genau.

INSERT/UPDATE/DELETE/UPDATE-OR-INSERT gelten als gespeicherte Prozeduren Rufen Sie die Klasse der Anweisungen auf, wenn sie mit der RETURNING-Klausel und nicht mit der Abfrageklasse der Anweisungen ausgeführt werden.

Das bedeutet, dass sie keine "resultset" aus vielen verschiedenen Zeilen zurückgeben, sondern eine Reihe von skalaren Parametern/Feldern zurückgeben.

Und Sie können nicht "loop" über die Menge, die überhaupt keine Zeilen enthält.


Die Dokumentation von Ihrem Link behauptet, dass

höchstens eine Zeile zu entfernen aus den Werten zurückzukehren, um eine RETURNING-Klausel, um gegebenenfalls enthalten kann

A DELETE Aussage RÜCKKEHR Zeile gelöscht

Der Schwerpunkt liegt in der Dokumentation selbst.

1

Sie so etwas tun könnte:

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 
+1

kann man auch ohne ': ID' Variable ausführen, die inner' DELETE' mit "WHERE CURRENT OF * CURSOR *" -Klausel ausführt, aber in Firebird 3 Cursor sind oft sehr langsam. –

+0

@ Arioch'Das wusste das nicht! Vielen Dank, dass Sie darauf hingewiesen haben. – skafinski

+0

öffnen Sie www.translate.ru und scannen Sie durch http://www.sql.ru/forum/1269227 und http://www.sql.ru/forum/1233785 –