我在PL/pgSQL中有一个函数,它试图回退一些数据的日期范围。我遇到的问题是,我似乎无法将双精度存储在变量中。无论我做什么,当在函数内运行时,值总是空的。当我从psql命令行运行查询时,它返回给我正确的数据。我还可以在另一列上运行查询,这不是双精度类型,它工作得很好。例如,如果我将列更改为"total_impressions_for_date_range",它将返回正确的数据。
我正在使用PostgreSQL 8.4
CREATE OR REPLACE FUNCTION rollback_date_range_revenue(campaign_id int,
begin_date timestamp, end_date timestamp, autocommit boolean)
RETURNS void AS $BODY$
DECLARE
total_impressions_for_date_range bigint;
total_clicks_for_date_range bigint;
total_revenue_for_date_range double precision;
total_cost_for_date_range double precision;
BEGIN
SELECT sum(revenue) INTO total_revenue_for_date_range
FROM ad_block_summary_hourly
WHERE ad_run_id IN (
SELECT ad_run_id FROM ad_run WHERE ad_campaign_id = campaign_id)
AND ad_summary_time >= begin_date
AND ad_summary_time < end_date
AND (revenue IS NOT NULL);
RAISE NOTICE 'Total revenue for given date range and campaign % was %',
campaign_id, total_revenue_for_date_range;
当我运行这个时,我总是得到收入的空值
SELECT rollback_date_range_revenue(8818, '2015-07-20 18:00:00'::timestamp,
'2015-07-20 20:00:00'::timestamp, false);
NOTICE: Total revenue for given date range and campaign 8818 was <NULL>
当我从函数外的命令行运行它时,它工作得很好
select sum(revenue) from ad_block_summary_hourly where ad_run_id in (
select ad_run_id from ad_run where ad_campaign_id = 8818) and ad_summary_time
>= '2015-07-20 18:00:00'::TIMESTAMP and ad_summary_time < '2015-07-20
20:00:00'::TIMESTAMP ;
sum
----------
3122.533
(1 row)
编辑
感谢a_hor_with_no_name和Patrick。这确实是一个问题与占位符我叫收入重叠与我的查询。这两个不能工作的查询都是双精度查询,这让我很吃惊。碰巧的是,这两个也是我与列名重叠的占位符。
有两件事可以从中吸取教训。
- 我采用了a_horse_with_no_name建议的p_占位符命名方案,以避免再次发生此问题。
- 发布一个完整的代码示例,这可以被专家更快地识别出来。
首先,PostgreSQL 8.4不再支持,所以你应该尽快升级到9.4。其次,您的函数显然被简化了,因为没有使用一些声明的变量,并且没有END
子句。这两点加在一起,给你一个答案有点猜测,但这里有。
尝试将double precision
转换为文本,或将其转换为to_char()
。RAISE NOTICE
期望插入表达式的字符串;可能在8.4中这不是自动的。
您还可以改进您的查询:
...
SELECT sum(sh.revenue) INTO total_revenue_for_date_range
FROM ad_block_summary_hourly sh
JOIN ad_run r USING (ad_run_id)
WHERE r.ad_campaign_id = campaign_id
AND sh.ad_summary_time BETWEEN begin_date AND end_date;
RAISE NOTICE 'Total revenue for given date range and campaign % was %',
campaign_id, to_char(total_revenue_for_date_range, '9D999');
...
问题的另一个潜在原因(由于缺乏信息而再次猜测)是函数参数或变量与两个表中的任何一个的列名之间的名称冲突。