2015-12-30 210 views
1

我在postgresql(版本9.4.4)中有一個相當複雜的功能,我需要一些幫助。如何在postgresql函數中使用循環查詢的變量

我有一個循環(有很多下面的工作)宣佈這樣我的函數內:

CREATE OR REPLACE function getRSI(
    psymbol varchar, 
    pstarttime timestamp with time zone, 
    pendtime timestamp with time zone, 
    pduration double precision, 
    ptable varchar 
    ) 
RETURNS SETOF rsi AS 
$BODY$ 
declare 
    row_data record; 
    -- some variables 
begin 
    FOR row_data IN SELECT datetime, value FROM "4" WHERE symbol = 'AAPL' 
    AND datetime BETWEEN '2015-11-23 09:30:00 -0500' AND 
    '2015-11-23 15:59:59-0500' LOOP 
     -- enter code here 
    END LOOP; 
end 
$BODY$ LANGUAGE plpgsql 

此作品完美,我可以得到我的函數的結果,並將它緊縮的所有號碼我。

我想獲得環路這樣的工作:

FOR row_data in select datetime, value from quote_ident(ptable) 
where symbol = quote_literal(psymbol) and datetime 
between quote_literal(pstarttime) AND quote_literal(pendtime) LOOP 

其中ptablepsymbolpstarttimependtime從函數調用傳遞的變量。

不過,我會是具有硬編碼表,並得到其他三件事高興能夠基於一個變量:

FOR row_data in select datetime, value from "4" where symbol = 
quote_literal(psymbol) and datetime between quote_literal(pstarttime) 
AND quote_literal(pendtime) LOOP 

是的,我知道我有一個後一個數字,沒有指定的表我可以在我目前的設置中做到這一點。

當我嘗試使用上述任一設置調用該函數時,我只是空白。任何幫助,將不勝感激。我找不到有關在for循環中使用變量的任何文檔,因此它可能無法使用。

+1

您應該提供一個完整的(最小)功能。完整的標題和聲明很重要。永遠是你的Postgres版本。 –

+0

@Erwin欣賞這個反饋,我更新了這個問題,即使你已經完全爲我回答了這個問題。謝謝! –

+0

'row_data'應該聲明爲'record'。我冒昧地把它關掉。 –

回答

4

你需要動態SQL與EXECUTE - 但只參數表名(或其他標識符) - 沒有必要參數

And do 不是將參數值連接到查詢中。這比較昂貴且容易出錯。改爲使用USING clause of EXECUTE

FOR row_data IN 
    EXECUTE ' 
    SELECT datetime, value FROM ' || quote_ident(ptable) || ' 
    WHERE symbol = $1 
    AND datetime between $2 AND $3' 
    USING psymbol, pstarttime, pendtime 
LOOP 
    -- do stuff 
END LOOP; 

或者使用format()

EXECUTE format(' 
    SELECT datetime, value FROM %I 
    WHERE symbol = $1 
    AND datetime between $2 AND $3', ptable) 
    USING psymbol, pstarttime, pendtime 

相關:

+0

完美的工作,謝謝! –

+1

@Erwin,在上面的行中,我們不應該在quote_ident部分之前添加連接管道,就像這樣?:SELECT datetime,value FROM'|| quote_ident(ptable)|| ' –

+0

@SébastienClément:哦,是的,謝謝你指出。 –

1

改變你的for循環這樣

FOR row_data in execute 'select datetime, value from "4" where symbol =' || 
quote_literal(psymbol) || 'and datetime between' || quote_literal(pstarttime) 
|| 'AND ' || quote_literal(pendtime) LOOP 
+0

你是我最喜歡的人!除了從'quote_literal(pendtime)||改變結尾'LOOP'到'quote_literal(pendtime)LOOP'完美運行!我花了一個小時,在我最終放棄和問道之前,如何做到這一點。 –

+0

謝謝... @BenHernandez – Sathish

相關問題