0

この実行時エラーはなぜですか?

ERROR: column reference "arrive" is ambiguous LINE 6: case when ( (cast('05:00' as time) >= Arrival)
詳細: PL/pgSQL 変数またはテーブル列のいずれかを参照できます。

問題は、case ステートメントがクエリにあり、「arrive」という列があるテーブルから選択していることです。到着という変数を宣言していません。PG は、そのような変数が宣言されていないことを確認して、参照が列への参照である必要があると結論付けないのはなぜですか?

以下にコードを添付します。私が目にする唯一の表向きの競合は、この関数によって返される送信テーブルの定義にあり、そこには「arrive」という列があり、一時テーブル 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'
4

1 に答える 1

1

実際にはかなり単純です。関数のパラメーターは、関数本体内のどこにでも表示されます (動的 SQL を除く)。これは、すべてのパラメーター ( INOUTINOUTVARIADICRETURNS 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;

一時テーブルを作成する必要はありません。1 つのステートメントですべてを実行できます。

于 2013-01-27T18:59:09.300 に答える