为什么会出现此运行时错误?
错误:列引用“到达”不明确
第6行:((演员('05:00'为时间)> =到达时的情况)
DETAIL:它可以指PL / pgSQL变量或表格列。
问题是,case语句在查询中,我从一个名为“到达”列的表中进行选择。我有 not 声明了一个名为arri的变量。为什么PG不能简单地检查是否没有声明这样的变量,并断定引用必须是列?
我附上以下代码。我看到的唯一表面冲突是在这个函数返回的传出表的定义中,其中有一个名为“到达”的列,并且在最终选择中使用列名对照临时表TT。
CREATE or replace function GetHourlyView
(v_whichDate date)
returns TABLE
(
stagecoach,
arrive time,
depart time,
t5am int,t6am int,t7am int,t8am int,t9am int,t10am int, t11am int,
t12pm int, t1pm int, t2pm int t3pm int,t4pm int,t5pm int,t6pm int,
t7pm int, t8pm int, t9pm int, t10pm int, t11pm int
)
as $body$
declare v_dow int := date_part('dow',v_whichDate);
begin
drop table if exists TT;
create temp table TT
(stagecoach varchar(25),
arrive time,
depart time,
t5am int,t6am int,t7am int,t8am int,t9am int,t10am int, t11am int,
t12pm int, t1pm int, t2pm int t3pm int,t4pm int,t5pm int,t6pm int,
t7pm int, t8pm int, t9pm int, t10pm int, t11pm int
) without OIDS on commit drop;
insert into TT
select * from
GetDailySchedule( v_whichDate);
-- (arrive=depart) means 'cancelled'
delete from TT where TT.arrive=TT.depart;
return QUERY
select
TT.stagecoach,
arrive,
depart,
case when ( (cast('05:00' as time) >= arrive) and (cast('05:00' as time) < depart )) then 1 else 0 end as t5am,
case when ( (cast('06:00' as time) >= arrive) and (cast('06:00' as time) < depart )) then 1 else 0 end as t6am,
<snip>
.
.
.
case when ( (cast('23:00' as time) >= arrive) and (cast('23:00' as time) < depart )) then 1 else 0 end as t11pm
from TT
;
drop table TT;
end
$body$
LANGUAGE 'plpgsql'
答案 0 :(得分:1)
实际上它非常简单:函数体内的任何地方都可以看到函数参数(动态SQL除外)。对于所有参数都是如此:IN
, OUT
, INOUT
, VARIADIC
以及RETURNS TABLE
子句中使用的任何列名。
你还有其他一些小错误。
tt.arrive
而不仅仅是arrive
。stagecoach
中RETURNS TABLE
缺少类型。plpgsql
。这是一个标识符。我还建议你调整你的语法风格。你生活在对立的世界。惯例是大写SQL关键字和小写标识符,而不是相反。请记住,PostgreSQL会自动将不带引号的标识符转换为小写。
除此之外,您的功能可以大大简化到纯SQL查询。我把它包装成一个SQL函数:
CREATE OR REPLACE FUNCTION gethourlyview(v_whichdate date)
RETURNS TABLE (
stagecoach text, arrive time, depart time
, t5am int, t6am int, t7am int, t8am int, t9am int, t10am int, t11am int
, t12pm int, t1pm int, t2pm int, t3pm int, t4pm int, t5pm int, t6pm int
, t7pm int, t8pm int, t9pm int, t10pm int, t11pm int
) AS
$body$
SELECT tt.stagecoach
,tt.arrive -- "depart" would cause conflict
,tt.depart
,CASE WHEN '05:00'::time >= tt.arrive
AND '05:00'::time < tt.depart THEN 1 ELSE 0 END -- AS t5am
,...
,CASE WHEN '23:00'::time >= tt.arrive
AND '23:00'::time < tt.depart THEN 1 ELSE 0 END -- AS t11pm
FROM getdailyschedule($1) tt
WHERE tt.arrive IS DISTINCT FROM tt.depart;
$body$ LANGUAGE sql;
无需创建临时表。你可以在一个声明中完成所有这些。