公用表表达式:关系不存在

Posted

技术标签:

【中文标题】公用表表达式:关系不存在【英文标题】:Common Table Expressions: Relation does not exist 【发布时间】:2018-09-17 07:49:02 【问题描述】:

我使用的是 10.3 版的 postgresql 我正在使用函数内部的公用表表达式。功能代码如下:

CREATE OR REPLACE FUNCTION subscriptions.to_supply_patients(
    character varying,
    timestamp with time zone)
    RETURNS void
    LANGUAGE 'plpgsql'

    COST 100
    VOLATILE 
AS $BODY$

declare
aws_sub_pro alias for $1; -- health professional aws_sub 
tour_date alias for $2; -- tour date to manage patients covered accounts
number_cover int; -- the number of account to manage
sub_list integer[]; -- array list for subscribers covered
no_sub_list integer[];-- array list for no subscribers covered
date_tour timestamp with time zone;--tour date to manage patients covered accounts converted with time zone converted to 23:59:59 
begin
select subscriptions.convert_date_to_datetime((select date(tour_date)),'23:59:59','0 days') into date_tour; -- function to convert time to 23:59:59
select count(*) from subscriptions.cover where aws_sub = aws_sub_pro into number_cover; -- global number of patient to cover
if number_cover > 0 then 
   begin
        if tour_date >= current_timestamp then -- if tour date is later than today date
           begin
                with cover_list as (
                                   select id_cover from subscriptions.cover where aws_sub = aws_sub_pro and cover_duration >0 and is_covered_auto = true 
                                    -- we selectionned here the patients list to cover for health pro with aws_sub = aws_sub_pro
                                   ),
                     sub_cover_list as (
                                        select id_subs from subscriptions.subscribers_cover inner join cover_list on cover_list.id_cover = subscribers_cover.id_cover
                                        -- list of subscribers covered
                                       ),
                     no_sub_cover_list as (
                                           select id_free_trial from subscriptions.no_subscribers_cover inner join cover_list on cover_list.id_cover = no_subscribers_cover.id_cover   
                                            -- list of no subscribers covered
                                           )
-----------------------------------------------------------------------------------------------------------------------------

                    select array( select id_subs from subscriptions.subscribers_cover inner join cover_list on cover_list.id_cover = subscribers_cover.id_cover 
                                ) into sub_list; -- convert list of subscribers covered into array list
                     if array_upper(sub_list,1) <>0 then -- if array list is not empty
                        begin
                             for i in 1 .. array_upper (sub_list,1) loop -- for every one in this list
                                  if date_tour = (select sub_deadline_date from subscriptions.subscription where id_subs =sub_list[i] ) then -- if tour date is equals to 
                                     -- the deadline date 
                                     begin
                                          update subscriptions.subscription
                                          set
                                             sub_expiration_date = sub_expiration_date + interval'30 days', -- add 30 days to the exp date
                                             sub_deadline_date = sub_deadline_date + interval'30 days', -- add 30 date to deadline date
                                             sub_source = aws_sub_pro, -- supply source is no the professional
                                             is_sub_activ = false -- we turn off patients subscription
                                          where id_subs = (select id_subs from subscriptions.subscription where id_subs =sub_list[i] );
                                     end;
                                   end if;
                             end loop;
                        end;
                     end if;
--------------------------------------------------------------------------------------------------------------------------------                 

                     select array(select id_free_trial from subscriptions.no_subscribers_cover inner join cover_list on cover_list.id_cover = no_subscribers_cover.id_cover   
                                 ) into no_sub_list;
                     if array_upper(no_sub_list,1) <>0 then
                        begin
                             for i in 1 .. array_upper (no_sub_list,1) loop
                                  if date_tour = (select expiration_date from subscriptions.free_trial where id_free_trial =no_sub_list[i] and is_free_trial_activ = true ) then
                                     begin
                                          update subscriptions.free_trial
                                          set
                                             expiration_date = expiration_date + interval'30 days'

                                          where id_free_trial = (select id_free_trial from subscriptions.free_trial where id_free_trial =no_sub_list[i] );
                                     end;
                                  end if;
                             end loop;
                        end;
                    end if; 
           end;
        else
           raise 'tour date must be later than today''s date' using errcode='71'; 
        end if;
   end;
else
   raise notice 'your cover list is empty. you don''t have any patient to cover' using errcode='70';
end if;
end;

$BODY$;

ALTER FUNCTION subscriptions.to_supply_patients(character varying, timestamp with time zone)
    OWNER TO master_pgsql_hygeexv2;

当我运行这个函数时,我得到以下错误:

错误:ERREUR:la 关系 «cover_list » n'existe pas LINE 1: ...rom subscriptions.no_subscribers_cover 内部加入 cover_list...

翻译:

(关系 «cover_list » 不存在)

我尝试在查询窗口中仅运行 CTE,但收到相同的错误消息。

我有什么遗漏吗?

【问题讨论】:

看起来应该可以了。这是标准的 PostgreSQL 吗?哪个版本?能贴出完整的 SQL 语句吗? 我已经回答了你的问题。 我知道您说您只尝试了 CTE,但在第二次循环之前您的查询肯定有错误。它使用 CTE cover_list,但这仅在第一条语句中可用。这里:select array(select id_free_trial from subscriptions.no_subscribers_cover inner join cover_list 好收获@ŁukaszKamiński !! 【参考方案1】:

CTE 是 SQL 语句的一部分,在它之外的任何地方都不可见。

因此您只能在带有WITH 子句的SELECT 语句中使用cover_list

要么在第二个 SELECT 语句中重复 WITH 子句,要么重构代码以便您只需要一个查询。

另一种方法是使用临时表。

【讨论】:

以上是关于公用表表达式:关系不存在的主要内容,如果未能解决你的问题,请参考以下文章

Redshift 错误:关系“临时表”不存在

PSQLException:错误:关系“表”不存在

greenplum 数据库“关系不存在”

MySQL 中不允许在递归公用表表达式中使用 LIMIT

Django 1.4 多个数据库外键关系(1146,“表'other.orders_iorder'不存在”)

EF5生成的数据库在存在多个关系时不创建连接表