2016-09-09 5 views
-1

은 내가 포스트 그레스에 SQL 서버에서 변환 기능 스크립트 지금은 내가 내 함수는 3 개 개의 매개 변수 (siteid bigint, datefrom timestamp, dateto timestamp)을 얻고, 내가 포함 된 테이블을 반환해야Postgres 함수에서 결과를 테이블로 반환하는 방법은 무엇입니까?

ERROR: structure of query does not match function result type

오류를 얻을 기능을 실행하고있어이 코드에서. 나는 "Return Query"를 사용했다.

나는이처럼 내 함수를 실행 해요 :

getrtbactivesiteplaces(1475, '2016-02-01', '2016-08-01') 

나는 나의 함수의 테이블로이 결과를 얻을 수 있습니까?

이 내 기능의 스크린 샷이다

{ 
CREATE OR REPLACE FUNCTION "whis2011"."getrtbactivesiteplaces"(IN siteid int8, IN datefrom timestamp, IN dateto timestamp) RETURNS SETOF "varchar" 
AS $BODY$ 

DECLARE 
siteid BIGINT; 
datefrom timestamp without time zone; 
dateto timestamp without time zone; 


BEGIN 


-- SET NOCOUNT ON added to prevent extra result sets from 
-- interfering with SELECT statements. 

    /* SQLWays Notice: SET TRANSACTION ISOLATION LEVEL READ COMMITTED must be called before procedure call */ 
-- SET TRANSACTION ISOLATION LEVEL READ COMMITTED 


    -- Insert statements for procedure here 
RETURN QUERY SELECT pl."Id", 
     pl."RtbActiveSiteId", 
     pl."AdPlaceId", 
     pl."AdPosition", 
     pl."Ctr", 
     pl."State", 
     pl."BidPrice", 
     pl."MinBidFloor", 
     pl."MinBidFloorCurrency", 
     pl."AverageCpm", 
     pl."AverageClickCost", 
     coalesce(SUM(ss."BidsCount"),0) AS BidsCount, 
     coalesce(SUM(ss."ShowsCount"),0) AS ShowsCount, 
     coalesce(SUM(ss."RealShowsCount"),0) AS RealShowsCount, 
     coalesce(SUM(ss."ClicksCount"),0) AS ClicksCount, 
     coalesce(SUM(ss."ClickLayerClicksCount"),0) as ClickLayerClicksCount, 
     coalesce(SUM(ss."ShowsCost"),0::money) AS ShowsCost, 
     coalesce(SUM(ss."ClicksCost"),0::money) AS ClicksCost, 
     coalesce(SUM(ss."BidsCost"),0::money) AS BidsCost, 
     coalesce(SUM(ss."SliderMovesCount"),0) AS SliderMovesCount 
    FROM "whis2011"."RtbActiveSitePlaces" pl 
    LEFT OUTER JOIN "whis2011"."RtbActiveSitePlaceStatistics" ss ON ss."RtbActiveSitePlaceId" = pl."Id" 
    WHERE ss."Date" >= datefrom AND ss."Date" < dateto AND pl."RtbActiveSiteId" = siteid 
    GROUP BY pl."Id", pl."RtbActiveSiteId", pl."AdPlaceId", pl."AdPosition", pl."Ctr", pl."State", pl."BidPrice", 
    pl."MinBidFloor", pl."MinBidFloorCurrency", pl."AverageCpm", pl."AverageClickCost"; 
END; 
$BODY$ 
LANGUAGE plpgsql 
COST 100 
CALLED ON NULL INPUT 
SECURITY INVOKER 
VOLATILE; 

} 
+1

을 문제가 그래픽 일 경우, 모든 수단은 스크린 샷을 포함하여. 코드라면 코드의 그림을 보여주지 마십시오. 실제 코드를 여기에 게시하십시오. – Gerrat

+0

함수가 테이블을 반환하면'select * from getrtbactivesiteplaces (1475, '2016-02-01', '2016-08-01') ' –

+1

http://meta.stackoverflow.com/questions/을 사용해야합니다. 285551/왜 코드를 올려야하는지에 대한 질문이 있으시면/285557 # 285557 –

답변

1

당신은 당신의 코드에 두 가지 문제를 가지고 내가이 개 권장 사항이를 개선을 위해.

우선 RETURNS SETOF varchar 대신에 RETURNS TABLE ...을 사용해야 함수가 반환하는 모든 열을 지정해야합니다. 두 번째로 세 개의 함수 매개 변수가 있습니다.이 매개 변수의 이름은 함수 블록에서 다시 선언되어 매개 변수 값을 마스킹합니다. 따라서 매개 변수 값이 사용되지 않으므로이 함수는 아무 것도 반환하지 않습니다.

셋째, 모든 합계를 하위 쿼리에 넣었습니다. 하위 쿼리는 읽기 쉽고 더 효율적입니다. 마지막으로, 함수 본문은 단일 SQL 문이므로이 함수를 PL/pgSQL 언어 함수보다 더 효율적인 SQL 함수로 만들어야합니다.

아래를 참조하십시오.

CREATE OR REPLACE FUNCTION "whis2011"."getrtbactivesiteplaces" 
    (IN siteid int8, IN datefrom timestamp, IN dateto timestamp) 
RETURNS 
             
  
    SETOF "varchar" 
   TABLE (id int, RtbActiveSiteId int, ...) -- add all fields 
AS $BODY$ 

             
  
    DECLARE siteid BIGINT; datefrom timestamp without time zone; dateto timestamp without time zone; 
   -- don't redeclare parameters!!! 

             
  
    BEGIN 
   -- not needed for a SQL function 
    -- Insert statements for procedure here 
    
             
  
    RETURN QUERY 
   SELECT pl."Id", -- SQL function uses simple SELECT 
     pl."RtbActiveSiteId", 
     pl."AdPlaceId", 
     pl."AdPosition", 
     pl."Ctr", 
     pl."State", 
     pl."BidPrice", 
     pl."MinBidFloor", 
     pl."MinBidFloorCurrency", 
     pl."AverageCpm", 
     pl."AverageClickCost", 
     ss.* 
    FROM "whis2011"."RtbActiveSitePlaces" pl 
    LEFT JOIN (
     SELECT "RtbActiveSitePlaceId" AS "Id" 
       coalesce(SUM("BidsCount"),0) AS BidsCount, 
       coalesce(SUM("ShowsCount"),0) AS ShowsCount, 
       coalesce(SUM("RealShowsCount"),0) AS RealShowsCount, 
       coalesce(SUM("ClicksCount"),0) AS ClicksCount, 
       coalesce(SUM("ClickLayerClicksCount"),0) as ClickLayerClicksCount, 
       coalesce(SUM("ShowsCost"),0::money) AS ShowsCost, 
       coalesce(SUM("ClicksCost"),0::money) AS ClicksCost, 
       coalesce(SUM("BidsCost"),0::money) AS BidsCost, 
       coalesce(SUM("SliderMovesCount"),0) AS SliderMovesCount 
     FROM "whis2011"."RtbActiveSitePlaceStatistics" 
     WHERE "Date" >= datefrom AND "Date" < dateto 
     GROUP BY "RtbActiveSitePlaceId") ss USING ("Id") 
    WHERE pl."RtbActiveSiteId" = siteid; 

             
  
    END; 
   -- not needed for a SQL function 
$BODY$ LANGUAGE sql STRICT STABLE; -- don't call on NULL input and use STABLE

당신은 다음과 같이이 함수를 호출 :

SELECT * FROM getrtbactivesiteplaces(1475, '2016-02-01', '2016-08-01'); 
+0

감사합니다! 지금 일하고있어. – Nikito

0

함수의 반환 형식이 setof varchar이지만, 같은 것을해야한다 :

RETURNS TABLE (Id    integer, 
       RtbActiveSiteId integer, 
       ... etc ... 
      ) 
+0

작동하지 않습니다! 실제로 스크립트는 작동하지만 아무 것도 반환하지 않습니다 (하지만 내 결과에 따라 적어도 2 개의 행을 반환해야합니다). – Nikito

관련 문제