PLPGSQL 数组赋值不起作用,“赋值中的数组下标不能为空”

Posted

技术标签:

【中文标题】PLPGSQL 数组赋值不起作用,“赋值中的数组下标不能为空”【英文标题】:PLPGSQL array assignment not working, "array subscript in assignment must not be null" 【发布时间】:2010-12-24 16:47:15 【问题描述】:

在循环结果中将手机号码分配给 varchar[] 时,会出现以下错误:

"赋值中的数组下标不能为空"

另外,我认为将成员 uuid 和组成员 uuid 合并为一个,按 user_id 分组的查询,我认为它可以做得更好,或者这甚至可能是它首先出错的原因!

非常感谢任何帮助..

非常感谢!

CREATE  OR REPLACE FUNCTION create_membermessage(in_company_uuid uuid, in_user_uuid uuid, in_destinationmemberuuids uuid[], in_destinationgroupuuids uuid[], in_title character varying, in_messagecontents character varying, in_timedelta interval, in_messagecosts numeric, OUT out_status integer, OUT out_status_description character varying, OUT out_value VARCHAR[], OUT out_trigger uuid[]) RETURNS record
    LANGUAGE plpgsql
    AS $$

DECLARE
    temp_count INTEGER;
    temp_costs NUMERIC;
    temp_balance NUMERIC;
    temp_campaign_uuid UUID;
    temp_record RECORD;
    temp_mobilenumbers VARCHAR[];
    temp_destination_uuids UUID[];
    temp_iterator INTEGER;
BEGIN

 out_status := NULL;
 out_status_description := NULL;
 out_value := NULL;
 out_trigger := NULL;



    SELECT INTO temp_count COUNT(*) FROM costs WHERE costtype = 'MEMBERMESSAGE' AND company_uuid = in_company_uuid AND startdatetime < NOW() AND (enddatetime > NOW() OR enddatetime IS NULL);

    IF temp_count > 1 THEN

        out_status := 1;
        out_status_description := 'Invalid rows in costs table!';
        RETURN;

    ELSEIF temp_count = 1 THEN

        SELECT INTO temp_costs costs FROM costs WHERE costtype = 'MEMBERMESSAGE' AND company_uuid = in_company_uuid AND startdatetime < NOW() AND (enddatetime > NOW() OR enddatetime IS NULL);

    ELSE

        SELECT INTO temp_costs costs FROM costs WHERE costtype = 'MEMBERMESSAGE' AND company_uuid IS NULL AND startdatetime < NOW() AND (enddatetime > NOW() OR enddatetime IS NULL);

    END IF;

    IF temp_costs != in_messagecosts THEN

        out_status := 2;
        out_status_description := 'Message costs have changed during sending of the message';
        RETURN;

    ELSE

        SELECT INTO temp_balance balance FROM companies WHERE company_uuid = in_company_uuid;
        SELECT INTO temp_count COUNT(*) 
          FROM users 
          WHERE (user_uuid = ANY(in_destinationmemberuuids))
             OR (user_uuid IN (SELECT user_uuid FROM targetgroupusers WHERE targetgroup_uuid = ANY(in_destinationgroupuuids)) )
         GROUP BY user_uuid;

        temp_campaign_uuid := generate_uuid('campaigns', 'campaign_uuid');
        INSERT INTO campaigns (company_uuid, campaign_uuid, title, senddatetime, startdatetime, enddatetime, messagetype, state, message) VALUES (in_company_uuid, temp_campaign_uuid, in_title, NOW() + in_timedelta, NOW() + in_timedelta, NOW() + in_timedelta, 'MEMBERMESSAGE', 'DRAFT', in_messagecontents);

        IF in_timedelta > '00:00:00' THEN


        ELSE

            IF temp_balance < (temp_costs * temp_count) THEN

                UPDATE campaigns SET state = 'INACTIVE' WHERE campaign_uuid = temp_campaign_uuid;
                out_status := 2;
                out_status_description := 'Insufficient balance';
                RETURN;

            ELSE

                UPDATE campaigns SET state = 'ACTIVE' WHERE campaign_uuid = temp_campaign_uuid;

                UPDATE companies SET balance = (temp_balance - (temp_costs * temp_count)) WHERE company_uuid = in_company_uuid;

                SELECT INTO temp_destination_uuids array_agg(DISTINCT(user_uuid)) 
                  FROM users 
                  WHERE (user_uuid = ANY(in_destinationmemberuuids))
                     OR (user_uuid IN(SELECT user_uuid FROM targetgroupusers WHERE targetgroup_uuid = ANY(in_destinationgroupuuids)));
RAISE NOTICE 'Array is %', temp_destination_uuids;  


                FOR temp_record IN (SELECT u.firstname, m.mobilenumber FROM users AS u LEFT JOIN mobilenumbers AS m ON m.user_uuid = u.user_uuid WHERE u.user_uuid = ANY(temp_destination_uuids)) LOOP
                    IF temp_record.mobilenumber IS NOT NULL AND temp_record.mobilenumber != '' THEN

--这是错误的地方 temp_mobilenumbers[temp_iterator] := ARRAY[temp_record.firstname::VARCHAR, temp_record.mobilenumber::VARCHAR]; temp_iterator := temp_iterator + 1;

                                 END IF;
                END LOOP;

                out_status := 0;
                out_status_description := 'Message created successfully';
                out_value := temp_mobilenumbers;

                RETURN;                                                 

            END IF;         

        END IF;

    END IF;

END$$;

【问题讨论】:

【参考方案1】:

天哪,在看到循环部分后,我发现它在声明变量时出错了!

temp_iterator INTEGER;

应该是

temp_iterator INTEGER := 0;

啊,终于是圣诞节了!

【讨论】:

这正是错误消息告诉你的内容 :-) 圣诞快乐。

以上是关于PLPGSQL 数组赋值不起作用,“赋值中的数组下标不能为空”的主要内容,如果未能解决你的问题,请参考以下文章

plpgsql 在我的 greenplum 4.3.5.x 中不起作用

java 函数参数赋值不起作用

将数组数组取消嵌套到 plpgsql 中的简单数组

Postgres plpgsql JSON 赋值

在plpgsql中循环数组维度

PLPGSQL 数组索引从 1 开始?