簡體   English   中英

如何將參數傳遞給日期函數

[英]How to pass a parameter into a date function

我正在嘗試創建一個簡單的函數,但似乎無法將參數傳遞給date函數。
這是函數:

CREATE OR REPLACE FUNCTION test(source int,days text)
RETURNS integer AS $totals$
declare
    totals integer;
BEGIN

   select 
           count(id) into totals
     from  ad
    where
       createdate::date = date(current_date - interval '$2' day) and
       source = $1;

   RETURN totals;

END;
$totals$ LANGUAGE plpgsql;

這是無效的語法: interval '$2' day 在運行SQL之前,變量不只是交換到位,還需要將正確的值傳遞給函數。

您可能打算將字符串'day'連接到字符串( text )變量$2的末尾,也稱為days (不是文字字符串'$2' )。 因此$2 || 'day' $2 || 'day'days || 'day' days || 'day'

因為這不是單個文字,所以您需要顯式轉換,而不僅僅是類型標簽,因此需要使用CAST($2 || 'day' AS interval)(days || 'day')::interval

@IMSoP已經發現您的語法錯誤。 但是,這可以通過多種方式更簡單,更快和更清潔。

CREATE OR REPLACE FUNCTION test(_source int, _days int)
  RETURNS integer AS
$func$
SELECT count(*)::int
FROM   ad a
WHERE  a.source = $1
AND    a.createdate::date = current_date - $2
$func$  LANGUAGE sql STABLE;
  • 首先,要從date減去天數,您可以只減去一個integer 因此,我在這里使用一個integer參數。

  • 您不需要像這樣的簡單函數就可以使用plpgsql。 改用SQL函數 -在較大的查詢上下文中可以“內聯”,因此在某些情況下可以進行更好的優化。

  • 該函數可以是STABLE

  • 您的函數中存在命名沖突 source顯然也是列名。 盡量避免這種情況。 常見的做法是在變量和參數前加上下划線(否則沒有特殊含義)。 您還可以使用函數名稱(或使用位置參數)對列名和/或參數名進行表限定,以使它們明確。 我都在這里

  • 假設id是您的PK列,因此定義了NOT NULLcount(*)count(id)相同,但更短,更便宜。 我將其轉換為integer ,因為count()將返回bigint

但是 ,在這里,我懷疑您命名不正確的列createdate實際上不是date而是timestamp (問題中缺少必需的表定義)。 在這種情況下,用不同的詞組查詢效率更高:

CREATE OR REPLACE FUNCTION test(_source int, _days int)
  RETURNS integer AS
$func$
SELECT count(*)::int
FROM   ad a
WHERE  a.source = $1
AND    a.createdate >= now() - interval '1 day' * $2
AND    a.createdate <  now() - interval '1 day' * ($2 - 1)
$func$ LANGUAGE sql STABLE;
  • 此表達式可修飾 ,因此效率更高。 它還可以在(createdate)上使用普通索引 ,或者在(source, createdate)上使用普通索引 -對於大表很重要。

  • 還演示了減去天數的另一種方法。 您可以將interval '1 day'相乘。 有關:

暫無
暫無

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

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