[英]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 NULL
, count(*)
與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.