2014-11-03 31 views
0

我有下面的查詢,我想變成一個函數。我寫的SQL 1周的company_id = 26304

SELECT t.* FROM crosstab(
    $$ 
    select company_id, row_number() OVER (ORDER BY year DESC) AS rn2, id 
    from 
    (select i.company_id, year, f.id, f.created_at, 
       row_number() OVER (PARTITION BY year 
           ORDER BY year DESC, f.created_at DESC NULLS LAST) AS rn 
    from 
    public.interactions i 
    inner join public.financials f on f.interaction_id = i.id 
    where company_id = 26304 
) t1 
    where rn= 1 limit 3 
    $$ 
    ) AS t (company_id int, financial_id_1 int, financial_id_2 int, financial_id_3 int); 

此SQL語句轉動我的數據集,並返回預期如下:

company_id financial_id_1 financial_id_2 financial_id_3 
26304  6796   6795   6786 

然而,當我試圖把它變成一個表函數,它引發以下錯誤:

CREATE FUNCTION public.returnfinancials (int4) RETURNS TABLE (company_id int, financial_id_1 int, financial_id_2 int, financial_id_3 int) 
as 
$$ 
SELECT t.* FROM crosstab(
    ' 
    select company_id, row_number() OVER (ORDER BY year DESC) AS rn2, id 
    from 
    (select i.company_id, year, f.id, f.created_at, 
      row_number() OVER (PARTITION BY year ORDER BY year DESC, f.created_at DESC NULLS LAST) AS rn 
    from 
    public.interactions i 
    inner join public.financials f on f.interaction_id = i.id 
    where company_id = $1 
) t1 
    where rn= 1 limit 3 
    ' 
    ) AS t (company_id int, financial_id_1 int, financial_id_2 int, financial_id_3 int); 
$$ 
LANGUAGE 'sql' 

電話:

select * from returnfinancials(23) 

拋出:

ERROR: there is no parameter $1 
Where: SQL function "returnfinancials" statement 1 
Line: 1 
+0

爲什麼它需要是一個函數,如果所有的函數包含一個單一的sql語句? – Falmarri 2014-11-03 21:09:29

+0

這將成爲我爲多家公司返回的較大數據集的一部分。像下面選擇 companyid, 公司名稱, 城市, 狀態, 國家, f.financial_id_1 從C公司 內加入returnfinancials(companyid)f。關於d.companyid = F。companyid – 2014-11-03 21:13:07

+0

嘗試用'where where company_id ='|| $ 1 ||''替換'where company_id = $ 1'' – Houari 2014-11-03 21:30:40

回答

0

嘗試更換

where company_id = $1 

通過

where company_id = '||$1||' 
1

問題是$1是一個文本字符串中。它被crosstab解釋爲查詢,但在crosstab函數調用的上下文中,調用函數的參數不可見。如crosstab它的self在執行時沒有向查詢傳遞任何參數,則會出現錯誤。

要解決這個問題,您應該將參數值替換爲您傳遞給交叉表的查詢字符串。

在特定情況下它的確定只是直接替代品,因爲該參數是integer

'.... where company_id = '||$1||' .... ' 

但一般而言,您應該小心SQL注入和它的乾淨和最安全始終如一地引用您的參數。請注意,'11'是SQL中的有效整數字面值;引用標識符總是合法的,這只是可選的數字。

所以取而代之,甚至是數字,我建議你使用:

'.... where company_id = '||quote_literal($1)||' ....' 

或使用format功能構建字符串:

format('.... where company_id = %L ....', $1) 

這樣,如果有人以後更改company_id到非數字類型,你沒有得到一個漂亮的SQL注入漏洞。

相關問題