5

Bir postgres UDF'de oluşturulmuş bir sorgu dizgim var, bunun sonucunu karşı birleşimler gerçekleştirmek için geçici bir tabloya koymak istiyorum. LIMIT ve OFFSET öğelerini kullanarak ve yalnızca diğer veri kümelerine karşı birleşmek istemiyorum, böylece verileri sonlandırmak için, sorgulama planındaki LIMIT işleci sonlandırılır). Temp tablosunu aşağıdaki ifadeyle oluşturmaya çalışıyorum.Postgres dinamik bir sql dizesinden yerel bir geçici tablo oluşturma (taahhütte bırakma)

CREATE LOCAL TEMP TABLE query_result ON COMMIT DROP AS EXECUTE query_string_; 

Ama aşağıdaki hata bildirimi almak:

********** Error ********** 

ERROR: prepared statement "query_string_" does not exist 
SQL state: 26000 
Context: SQL statement "CREATE LOCAL TEMP TABLE query_result ON COMMIT DROP AS EXECUTE query_string_" 
PL/pgSQL function "search_posts_unjoined" line 48 at SQL statement 

Ayrıca, ben statemen hazırlamaya çalıştı, ama şu ya sözdizimi alamadım.

CREATE OR REPLACE FUNCTION search_posts_unjoined(
    forum_id_ INTEGER, 
    query_ CHARACTER VARYING, 
    offset_ INTEGER DEFAULT NULL, 
    limit_ INTEGER DEFAULT NULL, 
    from_date_ TIMESTAMP WITHOUT TIME ZONE DEFAULT NULL, 
    to_date_ TIMESTAMP WITHOUT TIME ZONE DEFAULT NULL, 
    in_categories_ INTEGER[] DEFAULT '{}' 
    ) 
RETURNS SETOF forum_posts AS $$ 
DECLARE 
    join_string CHARACTER VARYING := ' '; 
    from_where_date CHARACTER VARYING := ' '; 
    to_where_date CHARACTER VARYING := ' '; 
    query_string_ CHARACTER VARYING := ' '; 
    offset_str_ CHARACTER VARYING := ' '; 
    limit_str_ CHARACTER VARYING := ' '; 
BEGIN 
    IF NOT from_date_ IS NULL THEN 
     from_where_date := ' AND fp.posted_at > ''' || from_date_ || ''''; 
    END IF; 

    IF NOT to_date_ IS NULL THEN 
     to_where_date := ' AND fp.posted_at < ''' || to_date_ || ''''; 
    END IF; 

    IF NOT offset_ IS NULL THEN 
     offset_str_ := ' OFFSET ' || offset_; 
    END IF; 

    IF NOT limit_ IS NULL THEN 
     limit_str_ := ' LIMIT ' || limit_; 
    END IF; 

    IF NOT limit_ IS NULL THEN 
    END IF; 

    CREATE LOCAL TEMP TABLE un_cat(id) ON COMMIT DROP AS (select * from unnest(in_categories_)) ; 

    if in_categories_ != '{}' THEN 
     join_string := ' INNER JOIN un_cat uc ON uc.id = fp.category_id ' ; 
    END IF; 

    query_string_ := ' 
    SELECT fp.* 
    FROM forum_posts fp' || 
     join_string 
    || 
    'WHERE fp.forum_id = ' || forum_id_ || ' AND 
    to_tsvector(''english'',fp.post_text) @@ to_tsquery(''english'','''|| query_||''')' || 
     from_where_date || 
     to_where_date || 
     offset_str_ || 
     limit_str_ 
    || ';'; 

    CREATE LOCAL TEMP TABLE query_result ON COMMIT DROP AS EXECUTE query_string_; 

    RAISE NOTICE '%', query_string_; 

    RETURN QUERY 
    EXECUTE query_string_; 
END; 
$$ LANGUAGE plpgsql; 

Ve söz konusu deyimi kaldırıldığında çalışır: Söz konusu

UDF

olduğunu. yerine

cevap

6

Kullanım:

EXECUTE ' 
CREATE TEMP TABLE query_result ON COMMIT DROP AS '|| query_string_; 
  • EXECUTE bütün beyanı.
    Sözdizimi formu CREATE TABLE foo AS EXECUTE <query> geçerli değil. Bu bağlamda, sadece bir gürültü sözcüğüdür ve yok sayılır.

Diğer details in the manual.

+0

Ahh "indirgeme düzeyleri" nin sevinçleri = D Çok takdir edildi. –

İlgili konular