postgresql - 错误: cursor "<unnamed portal>" does not exist

标签 postgresql plpgsql

根据此过程,光标将显示两行,但是当我执行此查询时,它显示错误:光标“未命名的门户”不存在 在图像表中

CREATE TABLE image
(
  id numeric(9,0) NOT NULL,
  nm_code character varying(100) NOT NULL,
  synonym text NOT NULL,
  CONSTRAINT synonym_id PRIMARY KEY (id)
)
INSERT INTO image(
            id, nm_code, synonym)
    VALUES (01,'13160101','CAR TYRE');
INSERT INTO image(
                id, nm_code, synonym)
        VALUES (01,'10000101','CAR TYRE');

旧版主表

CREATE TABLE legacymaster
(
  legacy_code character varying(20),
  source_data text,
)

insert into legacymaster (legacy_code,source_data) values ('123','WITH CAR TYRE FROM AUDI 2000')

mm_nounmodmaster表结构

CREATE TABLE mm_nounmodmaster
(
  nm_code character varying(18) NOT NULL,
  noun character varying(35),
  modifier1 character varying(35) NOT NULL,
  modifier2 character varying(35),
  modifier3 character varying(35),
  nm_type character(1) NOT NULL,
  nm_abbr character varying(200),
  nm_description character varying(80) NOT NULL,
  is_template character(1) DEFAULT 'N'::bpchar,
  )


    INSERT INTO mm_nounmodmaster(nm_code, noun, modifier1, modifier2, modifier3, nm_type, nm_abbr, 
            nm_description,is_template)
    VALUES ("10000101","ABRASIVE","--","--","","F","--","ABRASIVE",'Y')

    INSERT INTO mm_nounmodmaster(nm_code, noun, modifier1, modifier2, modifier3, nm_type, nm_abbr, 
                nm_description,is_template)
                VALUES ("13160101","TYRE","AUTOMOBILE","--","","F","TYR,AUTO","TYRE,AUTOMOBILE",'Y')
    INSERT INTO mm_nounmodmaster(nm_code, noun, modifier1, modifier2, modifier3, nm_type, nm_abbr, 
            nm_description,is_template)
            VALUES ("10020101","ACTUATOR","ELECTRICAL","--","--","F","ACTR,ELE","ACTUATOR,ELECTRICAL",'Y')

在nounmodmaster表中插入了三个记录,但在图像表同义词中包含“汽车轮胎”只有两个nm_codes。因此,当我执行此函数时,光标将执行 nounmodmaster 中的两行,除了最后一行,因为它与图像表不匹配

CREATE OR REPLACE FUNCTION func_source_based_nounmod(legacy_code_in character varying)
                  RETURNS refcursor AS
                $BODY$
                    declare 
                        source text;
                        nmcode character varying(50);
                        v_parent_Rec1 record;
                        v_parent_Rec2 record;
                        item_desc character varying(50);
                        noun_t character varying(50);
                        mod1 character varying(50);
                        CUR REFCURSOR;
                begin
                    --select source_data into source from legacymaster where source_data=legacy_code_in;
                    raise notice '1';
                    for v_parent_Rec1 in(SELECT id,nm_code,synonym FROM image)loop
                raise notice '2';
                        --if exists (select source_data from legacymaster where legacy_code=legacy_code_in) then
                raise notice '3';
                        IF exists (select source_data from legacymaster where legacy_code=legacy_code_in and source_data ilike '%'||v_parent_Rec1.synonym||'%') THEN
                raise notice '4';
                            FOR v_parent_Rec2 IN(SELECT DISTINCT AA.NM_CODE, NM_TYPE,
                        (CASE WHEN NM_ABBR IS NOT NULL THEN NM_ABBR ELSE '--' END) as NM_ABBR,
                        NM_DESCRIPTION, NM_CATEGORY,
                        (CASE WHEN image.NM_CODE IS NOT NULL THEN 'ACTIVE' ELSE 'INACTIVE' END) as STATUS,
                        (CASE WHEN NOUN IS NOT NULL AND NOUN <> '--' AND trim(both ' ' from NOUN) <> '' THEN NOUN ELSE '' END) || 
                        (CASE WHEN MODIFIER1 IS NOT NULL AND MODIFIER1 <> '--' AND TRIM(BOTH ' ' FROM MODIFIER1) <> '' THEN ',' || MODIFIER1 ELSE '' END) ||
                        (CASE WHEN MODIFIER2 IS NOT NULL AND MODIFIER2 <> '--' AND TRIM(BOTH ' ' FROM MODIFIER2) <> '' THEN ',' || MODIFIER2 ELSE '' END) ||
                        (CASE WHEN MODIFIER3 IS NOT NULL AND MODIFIER3 <> '--' AND TRIM(BOTH ' ' FROM MODIFIER3) <> '' THEN ',' || MODIFIER3 ELSE '' END) AS NOUNMOD,
                        is_template, Count(image.nm_code) AS CountOfnm_code from mm_nounmodmaster aa
                            inner join image on image.nm_code=aa.nm_code
                            where image.synonym =v_parent_Rec1.synonym and image.nm_code=v_parent_Rec1.nm_code group by aa.nm_code,image.nm_code)LOOP

                    --raise notice '%',v_parent_Rec2.noun;
                    --raise notice '%',v_parent_Rec2.modifier1;
                        END LOOP;
                        ITEM_DESC:=v_parent_Rec1.nm_code;
                    raise notice '%',ITEM_DESC;
                    raise notice '%',v_parent_Rec2.nm_code;
                    raise notice '%',v_parent_Rec2.NM_TYPE;
                    raise notice '%',v_parent_Rec2.NM_ABBR;
                    raise notice '%',v_parent_Rec2.NM_DESCRIPTION;
                    raise notice '%',v_parent_Rec2.NM_CATEGORY;
                    raise notice '%',v_parent_Rec2.NOUNMOD;
                    raise notice '%',v_parent_Rec2.CountOfnm_code;
                        --end if;
                        OPEN CUR FOR 
                    SELECT DISTINCT v_parent_Rec2.nm_code,v_parent_Rec2.NM_TYPE,v_parent_Rec2.NM_ABBR,v_parent_Rec2.NM_DESCRIPTION,v_parent_Rec2.NM_CATEGORY,v_parent_Rec2.NOUNMOD,v_parent_Rec2.CountOfnm_code;
                    close cur;
                        end if;
                        end loop;
                  raise notice '5';
                RETURN CUR;
                    end;
                $BODY$

通过传递Legacy_code_in参数,如果源数据字符串包含“Car Tyre”,则它位于legacymaster表中。然后它会显示两行与图像表比较

我需要

最佳答案

首先,您收到的错误是因为,除非您专门为游标指定了名称,否则 postgres 会返回一个具有特殊名称“未命名门户”的游标,并且它可以继续 1、2、3 等。

这通常没什么帮助,但幸运的是有一个简单的替代方案。您只需将光标作为参数传递给函数,这样您的过程就会开始:

CREATE OR REPLACE FUNCTION func_source_based_nounmod(legacy_code_in character varying, cur refcursor)

假设您从查询窗口调用此函数,您现在可以拥有如下所示的代码:

BEGIN;
select func_source_based_nounmod('123', 'mycursor');
FETCH ALL IN "mycursor";
COMMIT;

不幸的是,这很容易!鉴于您发布的数据,顺便说一句,您的函数中格式不正确并且缺少列,您会看到我传递的不是您似乎建议的“汽车轮胎”,而是“123”。这是必要的,因为否则你永远无法打开光标,因为你有

IF exists (select source_data from legacymaster 
where legacy_code=legacy_code_in and

因此legacy_code_in必须与legacymaster中的代码匹配。

然后你的问题就会变得更糟。

您的以下 SELECT 中有一个 Count() (FOR v_parent_Rec2 IN(SELECT DISTINCT AA.NM_CODE, NM_TYPE, etc.)。这意味着 SELECT 中的所有项目都需要位于 Group BY 中,而不仅仅是其中的一些项目!在这里,我在运行代码时遇到了一个特殊问题,因为上面的表结构缺少类别。

最后,这一切都在循环中。在此循环结束时,您将打开和关闭光标。您似乎误解了这样做,您将能够用连续的行填充光标。这不是它的工作原理。

类似地,您在关闭光标后返回光标(因此出现原始错误消息)。为了能够访问游标,返回游标时需要打开游标。

那么你如何解决这一切呢?我的建议是您使用临时表。调用函数之前清空表。无需在循环结束时打开和关闭游标,只需将行添加到临时表中即可。然后运行该函数后从表中读取。如果需要将结果集保存在游标中,只需在临时表上打开游标即可。

关于postgresql - 错误: cursor "<unnamed portal>" does not exist,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45319810/

相关文章:

database - 如何从 PostgreSQL 中的另一个函数调用表函数?

sql - 尝试传递日期类型的 FOREIGN KEY 会引发错误

sql - Postgres 添加唯一约束

sql - 触发更新以更新所有子节点

postgresql - 循环遍历 RECORD 的列

scala - 使用 JDBC 创建 PostgreSQL 触发器

postgresql - 哪种 PostgreSQL 复制解决方案适用于我的特定场景

sql - PostgreSQL 中具有互换列值的行的聚合

sql - Postgres 函数比查询/Postgres 8.4 慢

arrays - 在 plpgsql 中循环遍历数组维度