2014-07-01 76 views
1

我有一個返回類型爲TABLE的函數,我想從我的表中獲取某些列到該函數的RETURN TABLE類型中。當我執行該函數時,它不給出任何錯誤,但不返回任何記錄,儘管它應該根據我所擁有的條件返回一些記錄。 下面是我寫的代碼,有人可以讓我知道我哪裏出錯了嗎?PostgreSQL中函數的返回表類型

CREATE OR REPLACE FUNCTION ccdb.fn_email_details_auto() 
    RETURNS TABLE (code integer, area smallint, action smallint, flag smallint, ucount integer, view_cnt integer) AS 
$BODY$ 

DECLARE 
sec_col refcursor; 
cnt integer; 
sec_code ccdb.update_qtable%ROWTYPE; 

BEGIN 

SELECT COUNT(DISTINCT section_code) 
INTO cnt 
FROM ccdb.update_qtable 
WHERE entry_time::date = now()::date - interval '1 day'; 

OPEN sec_col FOR 
    SELECT * FROM ccdb.update_qtable WHERE entry_time::date = now()::date - interval '1 day'; 

FOR i IN 1..cnt 
LOOP 

FETCH sec_col INTO sec_code; 

    PERFORM section_code, ddu_area, ddu_action, status_flag, ccdb_ucount, ccdb_view_cnt 
FROM ccdb.update_qtable 
WHERE entry_time::date = now()::date - interval '1 day' AND section_code = sec_code.section_code 
ORDER BY ddu_area, ddu_action; 

END LOOP; 

CLOSE sec_col; 

END; 
$BODY$ 
    LANGUAGE plpgsql VOLATILE 
    COST 100; 
+0

您將需要提供與此相對應的表格定義和數據,否則我們需要精神力量來幫助。另外,爲什麼你使用顯式遊標,而不是'FOR ... SELECT ...'? –

回答

1

你的函數是做的空工作很多

您可以使用隱式遊標來簡化FOR loop,而不是更繁瑣昂貴的顯式遊標。
仔細看,事實證明你根本不需要這些。 用簡單的查詢從根本上簡化。我裹成一個SQL函數:

CREATE OR REPLACE FUNCTION ccdb.fn_email_details_auto() 
    RETURNS TABLE (code integer, area smallint, action smallint, flag smallint 
       , ucount integer, view_cnt integer) AS 
$func$ 

SELECT u.section_code, u.ddu_area, u.ddu_action, u.status_flag 
    , u.ccdb_ucount, u.ccdb_view_cnt 
FROM ccdb.update_qtable u 
WHERE u.entry_time >= now()::date - 1 
AND u.entry_time < now()::date  -- sargable! 
ORDER BY u.section_code, u.ddu_area, u.ddu_action; 

$func$ LANGUAGE sql; 

應該是速度,同時返回相同。
此外,使用這樣的:

WHERE u.entry_time >= now()::date - 1 
AND u.entry_time < now()::date 

代替:


             
  
    WHERE entry_time::date = now()::date - interval '1 day' 
  

另一種方法是sargable,並且可以使用在entry_time一個普通指標,這應該是對性能至關重要的。

+0

謝謝埃爾溫這工作了 –

+0

我有一個問題,我們應該什麼時候間隔計算時間差,什麼時候不? –

+0

@YousufIbnAkhtarSultan:不知道我明白這個問題。無論哪種方式,我建議你張貼另一個*問題*與所有必要的細節。評論不是新問題的地方。你可以隨時鏈接到這個上下文。 –

2

我能夠通過對SELECT語句使用RETURN QUERY來解決此問題,我在其中使用PERFORM。 下面提到的查詢幫助我實現了我的要求。

CREATE OR REPLACE FUNCTION ccdb.fn_email_details_auto() 
    RETURNS TABLE (code integer, area smallint, action smallint, flag smallint, ucount integer, view_cnt integer) AS 
$BODY$ 

DECLARE 
sec_col refcursor; 
cnt integer; 
sec_code ccdb.update_qtable%ROWTYPE; 

BEGIN 

SELECT COUNT(DISTINCT section_code) 
INTO cnt 
FROM ccdb.update_qtable 
WHERE entry_time::date = now()::date - interval '1 day'; 

OPEN sec_col FOR 
SELECT DISTINCT ON (section_code)* FROM ccdb.update_qtable WHERE entry_time::date = now()::date - interval '1 day'; 

FOR i IN 1..cnt 
LOOP 

FETCH sec_col INTO sec_code; 

RETURN QUERY 
SELECT section_code, ddu_area, ddu_action, status_flag, ccdb_ucount, ccdb_view_cnt 
FROM ccdb.update_qtable 
WHERE entry_time::date = now()::date - interval '1 day' AND section_code = sec_code.section_code 
ORDER BY ddu_area, ddu_action; 

END LOOP; 

CLOSE sec_col; 

END; 
$BODY$ 
    LANGUAGE plpgsql VOLATILE 
    COST 100; 
+0

不要使用它。這個功能的大部分工作都是沒有用的。 –