2017-07-26 2 views
0

Selon cette procédure, le curseur affiche deux lignes, mais lorsque j'exécute cette requête, il affiche ERREUR: le curseur "portail sans nom" n'existe pas Dans la table d'imageERREUR: le curseur "<portail sans nom>" n'existe pas

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'); 

table maître Legacy

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') 

structure de table de 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') 

dans la table nounmodmaster trois enregistrements sont insérés mais dans la table des synonymes image contient 'pneu de voiture' est seulement deux nm_codes. Alors, quand j'exécute ce curseur de la fonction exécutera deux lignes dans nounmodmaster sauf dernière ligne car il ne correspond pas à la table d'image

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$ 

En passant paramètre Legacy_code_in, il est dans le tableau de legacymaster, si la chaîne de données source contient « voiture Pneu'. il affiche deux lignes se comparent avec table d'image

i besoin

+0

On ne sait pas exactement ce que le code essaie de faire, et nous ne pouvons pas l'exécuter car nous n'avons pas la définition pour les tables référencées. Vous ouvrez un curseur pour une requête sans table, puis fermez-le, puis renvoyez-le. Huh? Comment cela devrait-il fonctionner? Avez-vous l'erreur lorsque vous appelez la fonction? Comment l'appelez-vous? –

+0

Je passe l'ancien code_in, il est dans l'ancienne table maître dans la table principale héritée si la chaîne de données source contient 'Pneu de voiture' alors il montre les deux lignes, pourquoi parce que dans la table d'image deux lignes contiennent la chaîne 'Pneu de voiture' en utilisant le curseur, c'est possible. – Gobinath

+0

Je ne peux pas voir une instruction 'CREATE TABLE' ou une instruction' SELECT' ici. –

Répondre

0

d'abord l'erreur que vous obtenez est parce que, à moins que vous donnez spécifiquement le curseur un nom, postgres retourne un curseur avec le nom spécial « sans nom portail "et il peut aller sur 1, 2, 3 etc

Ceci est assez inutile en général, mais heureusement, il existe une alternative facile. Vous passez simplement le curseur comme paramètre à la fonction, de sorte que votre procédure commencera:

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

En supposant que vous appelez cette fonction à partir d'une fenêtre de requête, vous pouvez maintenant avoir un code qui ressemble à:

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

Malheureusement, c'est le peu facile! Étant donné les données que vous avez publiées, lesquelles BTW ont été incorrectement formatées et les colonnes manquantes dans votre fonction, vous verrez que je n'ai pas passé 'pneu de voiture' comme vous sembliez le suggérer mais '123'. Cela était nécessaire parce que sinon vous ne avez jamais d'ouvrir le curseur, parce que vous avez

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

Alors legacy_code_in doit correspondre au code legacymaster.

Ensuite, vos problèmes s'aggravent.

Vous avez un Count() dans votre SELECT suivant (FOR v_parent_Rec2 IN (SELECT DISTINCT AA.NM_CODE, NM_TYPE, etc.) Cela signifie que tous les éléments du SELECT doivent être dans le groupe BY et pas seulement J'ai eu un problème particulier à faire fonctionner votre code, car la structure de votre tableau ci-dessus manquait de catégorie

Enfin, tout ceci est en boucle .A la fin de cette boucle, vous ouvrez et fermez le curseur. Pour être sous l'impression erronée, vous pourrez remplir le curseur avec des rangées successives, ce qui n'est pas le cas

De même, vous retournez le curseur après l'avoir fermé (d'où le message d'erreur original) . Pour pouvoir accéder au curseur, le curseur doit être ouvert lorsque vous le retournez.

Alors comment réparer tout cela? Ma recommandation est pour vous d'utiliser une table temporaire. Effacez la table avant d'appeler la fonction.Au lieu d'ouvrir et de fermer le curseur à la fin de votre boucle, ajoute simplement une ligne à la table temporaire. Et puis après avoir exécuté la fonction lire de la table. Si vous avez besoin du résultat dans un curseur, vous pouvez simplement ouvrir le curseur sur la table temporaire.