PL / pgSQL变量被列为列

时间:2014-08-08 10:09:07

标签: postgresql plpgsql

我的Postgres有问题,看起来很简单。我已经完成了我的研究,但我没有在网上看到任何类似的东西,并希望得到一些澄清:

这是在一个函数内部完成的,这里是整个代码:

BEGIN
    IF($5 IS NOT NULL) THEN
        BEGIN
            INSERT INTO "PushDevice"("DeviceId","PushNotificationId", "pushId","deviceType",sound)
            SELECT DISTINCT  d.id, $4,d.pushid,d.type,d.sound FROM "Device" d  inner join "DeviceLocation" dl ON  d.id = dl."DeviceId" 
            WHERE dl."FIPScode" in (select "FIPScode" from "CountyFIPS"  where "stateCode"=$5) AND dl."AppId"=$2 AND d.pushId is not null and d.pushId <>'' and d.pushId<>'1234-5678-9101-2345-3456' and d."isTest"=$3 and d."enableNotification"=TRUE and dl."isDeleted"=0
            AND NOT EXISTS (SELECT 1 FROM "PushDevice" t where t."DeviceId"=d.id AND t."PushNotificationId"=$4);
        END;
    ELSE 

        DECLARE "epiCentre" VARCHAR := NULL;
                        magnitude FLOAT = NULL;
        BEGIN
            SELECT polygon INTO "epiCentre" from alert  where id=$1 and "disablePush"=FALSE;
        END;

        IF("epiCentre" IS NOT NULL) THEN
        BEGIN
                INSERT INTO "PushDevice"("DeviceId","PushNotificationId", "pushId","deviceType","sound")
                SELECT DISTINCT  d.id, $4,d."pushId",d.type,d.sound FROM "Device" d  inner join "DeviceLocation" dl   ON  d.id = dl."DeviceId"
                WHERE  dl."AppId"=$2 AND d."pushId" is not null and d."pushId" <>'' and d."pushId" <>'1234-5678-9101-2345-3456' and d."isTest" =$3  and ST_Distance_Sphere(ST_GeometryFromText("epiCentre"), ST_GeometryFromText(geoPoint))<=d.radius * 1609.344 and magnitude>= d.magnitude and d."enableNotification"=1 and dl."isDeleted"=0
                AND NOT EXISTS (SELECT 1 FROM "PushDevice" t where t."DeviceId"=d.id AND t."PushNotificationId"=$4);
        END;
        END IF;

        RETURN QUERY SELECT pd.* FROM  "PushDevice" pd
        WHERE pd."PushNotificationId" =$4 and pd."sentAt" is null;

END IF;
END;

问题在于:

DECLARE "epiCentre" VARCHAR := NULL;
                        magnitude FLOAT = NULL;
        BEGIN
            SELECT polygon INTO "epiCentre" from alert  where id=$1 and "disablePush"=FALSE;
        END;

        IF("epiCentre" IS NOT NULL) THEN

有错误:

Procedure execution failed
ERROR:  column "epiCentre" does not exist
LINE 1: SELECT ("epiCentre" IS NOT NULL)
                ^
QUERY:  SELECT ("epiCentre" IS NOT NULL)
CONTEXT:  PL/pgSQL function "GetDevicesForPush... line 18 at IF. 

所以I F语句不知何故将epiCentre视为列而不是值。它甚至不知道它存在,虽然我在上面特别声明了它。

有什么想法吗?

2 个答案:

答案 0 :(得分:0)

我认为您必须发表许多BEGIN-END声明。 epiCentre的声明仅对第一个END有效。而IF就在那之后。因此,我会在整个ELSE部分使用Block。

http://www.postgresql.org/docs/8.3/static/plpgsql-structure.html

答案 1 :(得分:0)

你已经发现自己已经DECLARE must be placed before BEGIN of a each block

更重要的是,您根本不需要多个块。你也不需要变量。使用这种更简单,更安全,更快速的形式:

CREATE function foo(...)
   RETURNS ... AS
$func$
BEGIN
   IF($5 IS NOT NULL) THEN
      -- no redundant BEGIN!
      INSERT INTO  ... ;
      -- and no END!
   ELSIF EXISTS (SELECT 1 FROM alert
                 WHERE  id = $1
                 AND    "disablePush" = FALSE
                 AND    polygon IS NOT NULL   -- only if polygon can be NULL
                ) THEN
      INSERT INTO ... ;

      ...

   END IF;
END
$func$ LANGUAGE plpgsql;

更多详情: