PostgreSql在WHERE NOT中传递数组参数

时间:2016-12-28 00:14:28

标签: postgresql

我有一个用于创建物化视图的sql函数:

CREATE FUNCTION reports_mt_views(exclude_ids int[]) RETURNS void AS 
$BODY$
BEGIN
    EXECUTE 'CREATE MATERIALIZED VIEW tx_materialized AS
        SELECT tx.transaccion_id AS tx_transaccion_id,
        ...
        WHERE  creation_date > (current_date - interval '' 3 month '')
        AND (account_id <> ALL (' || $1 || '))'
RETURN;
END;
$BODY$ LANGUAGE plpgsql STRICT;

我也尝试过:

AND account_id NOT IN ' || $1|| ')'

但它不起作用。当我执行:

SELECT reports_mt_views(ARRAY [1,2,8,538524]);

我有这个错误:

ERROR:  operator does not exist: text || integer[]
LINE 171:     AND (account_id <> ALL (' || $1 || '))'
                                         ^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.

阵列本身没有问题我用FOR循环测试它并且有效。但进入条件却没有。我错过了什么?

1 个答案:

答案 0 :(得分:0)

解决方案是将数组作为文本连接,然后可以通过子句读取,而不是

   package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
)

type Page struct {
    Title string
    Body  []byte
}

func (p *Page) save() error {
    filename := p.Title + ".txt"
    return ioutil.WriteFile(filename, p.Body, 0600)
}

func loadPage(title string) (*Page, error) {
    filename := title + ".txt"
    body, err := ioutil.ReadFile(filename)
    if err != nil {
        return nil, err
    }
    return &Page{Title: title, Body: body}, nil
}

func viewHandler(w http.ResponseWriter, r *http.Request) {
    title := r.URL.Path[len("/view/"):]
    p, _ := loadPage(title)
    fmt.Fprintf(w, "<h1>%s</h1><div>%s</div>", p.Title, p.Body)
}

func main() {
    http.HandleFunc("/view/", viewHandler)
    http.ListenAndServe(":8080", nil)
}

它可以用作:

CREATE OR REPLACE FUNCTION pps.reports_mt_views(exclude_ids integer[])
...
DECLARE
    in_accounts ALIAS FOR $1;
    out_accounts  TEXT;
BEGIN
    out_accounts := in_accounts;
    out_accounts := trim(leading '{' FROM out_accounts);
    out_accounts := trim(trailing '}' FROM out_accounts);