2017-12-21 4 views
0

Ich habe die folgende Funktion erfolgreich kompiliert. Wenn ich select schema.funtion_name(); tun, wird die Funktion ausgeführt, aber es gibt keine in der Tabelle eingefügten Zeilen schema.table_insert:plpgsql Funktion, die Daten nicht wie beabsichtigt einfügen

CREATE OR REPLACE FUNCTION schema.function_name() 
RETURNS void AS 
$BODY$ 
DECLARE cur_1 CURSOR FOR 
    Select col1 from schema.table1 
    union 
    select col1 from schema.table2 
    union 
    select col1 from schema.table3 
    union 
    select col1 from schema.table4; 

BEGIN 
    FOR rec_i in cur_1 LOOP 
     insert into schema.table_insert (col1,col2,col3) 
     select col1,col2,col3 
     from schema.view 
     where col1=rec_i.col1 

     commit; 
    END LOOP;  
END; 
$BODY$ 
LANGUAGE plpgsql STABLE 

Der Auswahl in Cursor cur_1 mehr als 900 000 Datensätze zurückgibt. Wenn ich die Insert-Anweisung separat für einen einzelnen Datensatz verwende, wird der Datensatz in die Tabelle eingefügt.

+0

[So haben Sie Ihre Antwort?] (Https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) –

Antwort

1

Ich habe die folgende Funktion erfolgreich kompiliert.

Nein, haben Sie nicht.

Für den Anfang sind plpgsql Funktionen nicht "kompiliert". Bei der Erstellung werden nur oberflächliche Syntaxprüfungen durchgeführt, dann wird der Funktionskörper unverändert gespeichert. Keine Zusammenstellung. Späte Bindung. Geschachtelte SQL-Anweisungen werden als vorbereitete Anweisungen behandelt.

Abgesehen davon kann die Funktion, die Sie anzeigen, überhaupt nicht erstellt werden. Es ist syntaktischer Unsinn. Fehlendes Semikolon nach der INSERT. COMMIT macht keinen Sinn und ist in plpgsql nicht erlaubt. Sie benötigen dazu keinen Cursor. Noch Schleifen. Verwenden Sie eine einfache SQL-Anweisung:

INSERT INTO schema.table_insert (col1, col2, col3) 
SELECT v.col1, v.col2, v.col3 
FROM schema.view v 
JOIN (
    SELECT col1 FROM schema.table1 
    UNION 
    SELECT col1 FROM schema.table2 
    UNION 
    SELECT col1 FROM schema.table3 
    UNION 
    SELECT col1 FROM schema.table4; 
    ) sub USING (col1); 

Equivalent kann schneller sein:

INSERT INTO schema.table_insert (col1, col2, col3) 
SELECT v.col1, v.col2, v.col3 
FROM schema.view v 
WHERE EXISTS (SELECT 1 schema.table1 WHERE col1 = v.col1) 
OR  EXISTS (SELECT 1 schema.table2 WHERE col1 = v.col1) 
OR  EXISTS (SELECT 1 schema.table3 WHERE col1 = v.col1) 
OR  EXISTS (SELECT 1 schema.table4 WHERE col1 = v.col1); 

Kann in einer Funktion eingewickelt werden, aber plpgsql ist übertrieben. Und STABLE, wäre falsch für eine Funktion, die eine INSERT enthält. Ich schlage eine einfache SQL-Funktion vor und VOLATILE ist die Standardeinstellung und richtig für diese.

CREATE OR REPLACE FUNCTION schema.function_name() 
    RETURNS void AS 
$func$ 
INSERT ... 
$func$ LANGUAGE sql; 
Verwandte Themen