2016-10-22 16 views
0

私はpl/pgsqlを初めて使用しています。次の関数を実行しようとしていますが、結果として0レコードが返されます。キャストされたtimeStampがPL/pgsqlで正しい結果を返さない

select detectselect(1,'2016-01-21 0:0:0','2016-01-23 0:0:0'); 

として

CREATE OR REPLACE FUNCTION public.detectselect (i_channelID integer,te_startTime text,te_endTime text) 
RETURNS SETOF detect_inst AS $BODY$ 
declare 
    r detect_inst%rowtype; 
    tstz_endTime timestamp without time zone; 
    tstz_startTime timestamp without time zone; 
BEGIN 
    tstz_endTime = to_timestamp(te_endTime,'DD/MM/YYYY hh24:mi:ss')::timestamp without time zone; 
    tstz_startTime = to_timestamp(te_startTime,'DD/MM/YYYY hh24:mi:ss')::timestamp without time zone; 
    for r in SELECT * FROM detect_inst d WHERE d."ChannelID" = i_channelID AND d."EndTime" >= tstz_startTime AND d."EndTime" < tstz_endTime loop 
     return next r; 
    end loop; 
    RETURN; 
END; 
$BODY$ LANGUAGE plpgsql; 

コールが、私はこのように静的なタイムスタンプ値を与えるとき、それはあなたの関数は非常に複雑である

CREATE OR REPLACE FUNCTION public.detectselect (i_channelID integer,te_startTime text,te_endTime text) 
RETURNS SETOF detect_inst AS $BODY$ 
declare 
    r detect_inst%rowtype; 
    tstz_endTime timestamp without time zone; 
    tstz_startTime timestamp without time zone; 
BEGIN 
    tstz_endTime = to_timestamp(te_endTime,'DD/MM/YYYY hh24:mi:ss')::timestamp without time zone; 
    tstz_startTime = to_timestamp(te_startTime,'DD/MM/YYYY hh24:mi:ss')::timestamp without time zone; 
    for r in SELECT * FROM detect_inst d WHERE d."ChannelID" = i_channelID AND d."EndTime" >= '2016-01-21 0:0:0' AND d."EndTime" < '2016-01-23 0:0:0' loop 
     return next r; 
    end loop; 
    RETURN; 
END; 
$BODY$ LANGUAGE plpgsql; 
+0

なぜあなたはそれを最初に「テキスト」として渡していますか?パラメータを 'timestamp'として宣言し、' to_timestamp() 'を取り除くだけで、関数全体をより簡単にすることができます。プラス: 'to_timestamp()'を使用した場合、キャスト:: :: timestampは –

+0

です。タイムスタンプとしてパラメータを宣言すると、関数をどのように呼び出すべきですか? –

答えて

1

正しい結果を与えます。 PL/pgSQLは必要なく、結果を返すために(遅い)カーソルは必要ありません。

また、はるかに高速になりますプレーンなSQL関数に単純化することができます。

CREATE OR REPLACE FUNCTION public.detectselect (i_channelID integer, te_startTime timestamp, te_endTime timestamp) 
    RETURNS SETOF detect_inst AS 
$BODY$ 
    SELECT * 
    FROM detect_inst d 
    WHERE d."ChannelID" = i_channelID 
    AND d."EndTime" >= te_starttime 
    AND d."EndTime" < te_endtime 
$BODY$ 
LANGUAGE sql; 

あなたはそれを呼び出す:

select * 
from detectselect(1, timestamp '2016-01-21 00:00:00', timestamp '2016-01-23 00:00:00'); 

あなたはまた、これらの恐ろしいを避ける必要があります引用符で囲まれた識別子。彼らははるかに問題があり、価値があります。

関連する問題