lima-city: Webhosting, Domains und Cloud
0 Pluspunkte 0 Minuspunkte

Ich habe eine stored procedure wo ich mit dynamic SQL Zeilen löschen möchte die Energy=0 haben. Das funktioniert solange ich String-Verkettung verwende. Beim Versuch mit einer USING Klausel tritt aber ein Fehler auf.

    drop table if exists mysolar;
    
    create table mysolar (
        time        timestamptz not null,
        energy      double precision,
        eenergy     double precision,
        ienergy     double precision
    );
    
    select create_hypertable('mysolar',by_range('time'));
    
    insert into mysolar(time,energy,eenergy,ienergy)
    values
    ('2023-02-24 17:20:33',22.13299942,0.273999989,21.8589992),
    ('2023-02-24 17:21:33',22.13500023,0.273999989,21.8610000),
    ('2023-02-24 17:22:33',22.13699913,0.273999989,21.8630008),
    ('2023-02-24 17:23:33',22.13899994,0.273999989,21.8649997),
    ('2023-02-24 17:24:33',22.14299965,0.273999989,21.8689994),
    ('2023-02-24 17:25:33',0,0,0),
    ('2023-02-24 17:26:33',22.15099907,0.273999989,21.8770008),
    ('2023-02-24 17:27:33',22.15600014,0.273999989,21.8819999),
    ('2023-02-24 17:28:33',22.15999985,0.273999989,21.8859996),
    ('2023-02-24 17:29:33',22.16300011,0.273999989,21.8889999),
    ('2023-02-24 17:30:33',22.16500092,0.273999989,21.8910007),
    ('2023-02-24 17:31:33',22.16699982,0.273999989,21.8929996),
    ('2023-02-24 17:32:33',22.16900063,0.273999989,21.8950004),
    ('2023-02-24 17:34:12',22.17099953,0.273999989,21.8969993),
    ('2023-02-24 17:35:12',22.17300034,0.273999989,21.8990001),
    ('2023-02-24 17:36:12',22.17399979,0.273999989,21.8999996),
    ('2023-02-24 17:37:12',22.17499924,0.273999989,21.9009990),
    ('2023-02-24 17:38:12',22.17700005,0.273999989,21.9029998),
    ('2023-02-24 17:39:12',22.1779995,0.273999989,21.9039993),
    ('2023-02-24 17:40:12',22.17900085,0.273999989,21.9050006);

    create or replace procedure myf_proc(tblname text)
    language plpgsql
    as
    $$
    declare
        tablename text := tblname;
        qry text;
    begin
        --qry := 'delete from ' || tablename || ' where energy = 0;'; -- das funktioniert
        qry := 'delete from $1 where energy = 0;';
        execute qry using tablename;
        --raise notice 'QUERY :> %', qry;
    end;
    $$;
    
    call myf_proc('"mysolar"');

Die Prozedur kompiliert zwar aber ich erhalte einen Laufzeitfehler.

ERROR: syntax error at or near "$1" where: PL/pgSQL function myf_proc(text) line 8 at EXECUTE

von  

1 Antwort

0 Pluspunkte 0 Minuspunkte

Platzhalterbasierte USING Parameter ($1, $2, ...) in EXECUTE Statements mit dynamischem SQL können nur für Werte, nicht für SQL Objekte wie Tabellen oder Spaltennamen verwendet werden. In deinem Fall möchtest du den Tabellennamen dynamisch einsetzen, aber das funktioniert nicht mit USING. Stattdessen musst du die Zeichenkette direkt im SQL-Statement zusammenbauen (wie du es mit || bereits gemacht hast).

qry := 'delete from ' || quote_ident(tablename) || ' where energy = 0;';
execute qry;

Die USING-Klausel dient dazu Werte sicher zu übergeben aber nicht Strukturen wie Tabellennamen oder Spaltennamen.

von (395 Punkte)