1

Temat: Problem z językiem plpgsql.

DECLARE

kategorie_id_new integer;
drzewo_id_new text;

BEGIN

IF (TG_OP = 'DELETE') THEN
kategorie_id_new = OLD."kategorie_id";
ELSE
kategorie_id_new = NEW."kategorie_id";
END IF;

drzewo_id_new := "2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,1303,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,1351,1";
UPDATE kategorie as c SET wszystkich_produktow = (SELECT count(*) FROM produkty WHERE kategorie_id IN (drzewo_id_new)) WHERE id = kategorie_id_new;


RETURN NEW;
END; 

2

Odp: Problem z językiem plpgsql.

W postgresie jak uzyjesz " to baza traktuje zawartość jak nazwę kolumny/tabeli ogólnie jakiegoś obiektu w bazie. Spróbuj użyć ' aby zdefiniować ciąg.

3

Odp: Problem z językiem plpgsql.

Próbuje coś takiego:

UPDATE kategorie as c SET c.wszystkich_produktow = (SELECT count(*) FROM produkty WHERE kategorie_id IN (c.drzewo_id::text)) WHERE c.id = "kategorie_id_new";

Jednak otrzymuje błąd:

BŁĄD:  operator nie istnieje: integer = text

Np gdy wstawie coś takiego:

UPDATE kategorie as c SET c.wszystkich_produktow = (SELECT count(*) FROM produkty WHERE kategorie_id IN ('1,2,3')) WHERE c.id = "kategorie_id_new";

To mimo tego otrzymuje ten sam błąd jakby nie akceptował typ danych "text"

Jest na to jakaś rada ? PO prostu problem jest z tym że w IN () jak daje ciag '1,2,3' lub 1,2,3 (bez cudzysłowów)
to otrzymuje bląd

BŁĄD:  operator nie istnieje: integer = text

tak jakby po IN można było dać tylko typ integer co jest troche dziwne hmm

Ostatnio edytowany przez Sajrox (2009-04-27 13:42:53)

4

Odp: Problem z językiem plpgsql.

Możesz przedstawić to całą funkcję, od 'create function' do końca.

5

Odp: Problem z językiem plpgsql.

Nie jestem pewny:), ale może spróbuj takiego zapisu  '{1,2,3}'.

6

Odp: Problem z językiem plpgsql.

Nie no nie ma co kombinować.
Nie możesz napisac

kategorie_id IN ('1,2,3')

bo prawdopodobnie kategorie_id jest typu integer a '1,2,3' to napis. Juz lepiej napisać

kategorie_id IN (1,2,3)

Jak pokaże całą funkcję w szczególności separator ciała to będzie można spróbować z dynamicznym sqlem.

7

Odp: Problem z językiem plpgsql.

Podaje całą funkcje:

DECLARE
      kategorie_id_new integer;
      moje_id  integer;
BEGIN

IF (TG_OP = 'DELETE') THEN
      kategorie_id_new = OLD."kategorie_id";
ELSE
      kategorie_id_new = NEW."kategorie_id";
END IF;

moje_id = 1,2,3,4;


UPDATE kategorie SET wszystkich_produktow = (SELECT count(*) FROM produkty WHERE kategorie_id IN (moje_id)) WHERE id = kategorie_id_new;

RETURN NEW;
END; 

Przypisuje ją do tabeli jako trigger i po dodania do tej tabeli rekordu funkcja powinna się uruchomić i prawidłowo wszystko policzyć. Jednak dostaje błąd:

ERROR:  query "SELECT  1,2,3,4" returned 4 columns
CONTEXT:  PL/pgSQL function "liczba_produktow" line 18 at assignment

Generalnie jak ręcznie wpisze  IN(1,2,3,4)  to działa. Jednak gdy w IN(moja_zmienna)  podam zmienna to jest problem.

Czemu się tak dzieje ? Może źle przypisuje ten ciąg do zmiennej.
Dodam że gdy zmienna moje_id jest typu text i wartość przypisuje do niej tak:

moje_id = '1,2,3,4';

Także nie działa sad

ERROR:  operator does not exist: integer = text
LINE 1: ...(SELECT count(*) FROM produkty WHERE kategorie_id IN ( $1 ))...

8

Odp: Problem z językiem plpgsql.

Nie no bez jaj smile, co to niby ma oznaczać

moje_id = 1,2,3,4;

Prosiłem o całą funkcję od 'CREATE FUNCTION' ale się nie zrozumieliśmy. Powiedz mi w jaki sposób ograniczasz ciało funkcji.
Czyli zazwyczaj definicja funkcji wygląda tak

create function nazwa(argumenty) returns typ_zwracany as ...

i w miejscu  '...' pojawia się separator. Jakiego ty użyłeś?
Acha i tak na końcu to w plpgsql przypisanie zapisuje się operatorem ':='.

9

Odp: Problem z językiem plpgsql.

No właśnie wkleiłem całą funkcje smile

Podaje jeszcze raz to co uzyskałem przez Export:

CREATE FUNCTION liczba_ofert() RETURNS trigger
    AS $$DECLARE

my_id int;

BEGIN

IF (TG_OP = 'DELETE') THEN

my_id = OLD.produkty_id;

ELSE

my_id = NEW.produkty_id;

END IF;

UPDATE produkty SET wszystkich_ofert = (SELECT count(*) FROM oferty WHERE produkty_id = my_id AND czy_aktywna = true) WHERE id = my_id;
UPDATE produkty SET cena_min = (SELECT cena FROM oferty WHERE produkty_id = my_id AND czy_aktywna = true ORDER BY cena ASC LIMIT 1) WHERE id = my_id;
UPDATE produkty SET cena_max = (SELECT cena FROM oferty WHERE produkty_id = my_id AND czy_aktywna = true ORDER BY cena DESC LIMIT 1) WHERE id = my_id;


IF(TG_OP <> 'DELETE') THEN

RETURN NEW;

ELSE

RETURN OLD;

END IF;    

END;$$
    LANGUAGE plpgsql;

i wsio smile

10

Odp: Problem z językiem plpgsql.

No dobra to moze spróbuj zapytaniem dynamiczym. Coś w stylu

moje_id = '1,2,3,4';
EXECUTE 'UPDATE kategorie SET wszystkich_produktow = (SELECT count(*) FROM produkty WHERE kategorie_id IN      
                ('||moje_id||')) WHERE id = kategorie_id_new';

Powinno zadziałać. To chyba to co chciałeś.

11

Odp: Problem z językiem plpgsql.

Udał się smile
Troche musiałem jeszcze pokombinować ale wkońcu działa. Pomocne było tutaj słowo EXECUTE oraz '|| ||'
Po prostu brakuje mi podstaw z tej dziedziny hmm

Oto moj kod może się komuś przyda:

DECLARE

kategorie_id_new integer;
moje_drzewo_id text;

BEGIN

IF (TG_OP = 'DELETE') THEN

kategorie_id_new = OLD."kategorie_id";

ELSE

kategorie_id_new = NEW."kategorie_id";

END IF;

SELECT drzewo_id INTO moje_drzewo_id FROM kategorie WHERE id = kategorie_id_new;

EXECUTE 'UPDATE kategorie SET wszystkich_produktow = (SELECT count(*) FROM produkty WHERE kategorie_id IN ('||moje_drzewo_id||')) WHERE id = ('||kategorie_id_new||')';

RETURN NEW;

END; 

Dzięki wielkie za pomoc !! Na pewno będę tu często zaglądał wink