簡體   English   中英

如何將天數傳遞給Postgres函數?

[英]How to pass the number of days to a Postgres function?

函數getAvgByDay()中的參數days不起作用,我猜是因為它在引號內:

CREATE OR REPLACE FUNCTION getAvgByDay(days int)
RETURNS TABLE ( average text,
                date timestamp with time zone
               ) AS
$func$
BEGIN
RETURN QUERY
SELECT to_char( AVG(measure), '99999D22') AS average, ( now() - interval '$1 day') AS date
FROM (
        SELECT mes.date, mes.measure
        FROM measures mes
        WHERE mes.date < ( now() - interval '$1 day')
    ) AS mydata;
END
$func$ 
LANGUAGE plpgsql;

字符串中沒有內插。 但是您可以連接字符串並將其強制轉換為一個間隔。 嘗試:

... concat(days, ' day')::interval ...

或者,您可以使用format() ,它可能與您最初擁有的內容更接近:

... format('%s day', days)::interval ...

假設該列measures.date實際上是數據類型timestamptz而不是date

CREATE OR REPLACE FUNCTION get_avg_by_day(_days int)
  RETURNS TABLE (average text, ts timestamptz) AS  -- not using "date" for a timestamp
$func$
SELECT to_char(avg(measure), '99999D22') -- AS average
     , now() - interval '1 day' * $1     -- AS ts
FROM   measures m
WHERE  m.date < now() - interval '1 day' * $1
$func$  LANGUAGE sql;
  • 不需要PLpgSQL,可以是一個簡單的SQL函數。
  • 無需子查詢。 只增加復雜性和成本,卻沒有收益。
  • 在外部查詢級別不需要列別名。 不使用那些,因為在RETURNS子句中定義了可見的列名。
  • 不需要多余的括號。 無論如何, 運算符優先級可以按需工作。 (在這種情況下也沒有害處。)
  • 如果可以避免,請不要在Postgres中使用CaMeL大小寫標識符。
  • 不要將timestamptz列稱為“日期”。 這是誤導。 使用“ ts”代替。
  • 最重要的是:您對此表示懷疑,並且已經解釋了“粘滯位”:字符串內無插值。 但是只需將時間單位乘以integer輸入即可減去給定的天數:

     interval '1 day' * $1 

    這比字符串連接更快,更干凈。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM