Oracle9i: Funkcja zwraca inną wartość niż zapytanie

0

Werja ORACLE:
Oracle9i Release 9.2.0.8.0 - Production
PL/SQL Release 9.2.0.8.0 - Production

Sprawdzane poprzez: SQL Developer

TabelaA (
...
wartosc number(10,0),
kod VARCHAR2(6 CHAR)
);

TabelaB (
...
a_kod VARCHAR2(6 BYTE)
);
FUNCTION fun(kod varchar2) RETURN number
IS
  wynik number(10,0) := 0;
BEGIN
  select a.wartosc into wynik
  from TabelaB b 
  join TabelaA on a.kod = b.a_kod
  where b.a_kod = kod;
  dbms_output.put_line('f-> ' || wynik);
  return wynik;
END;
select a.wartosc
  from TabelaB b 
  join TabelaA on a.kod = b.a_kod
  where b.a_kod = kod;

Jeżeli użyję zapytania poza obrębem funkcji zwracana jest wartość 5 (jest to prawidłowy wynik), a po wywołaniu funkcji zwracany jest wynik: 6
Jedynie pola tabel nie są wszystkie podane, bo to nie istotne. Funkcja i wywołania tak jak jest to w bazie.

declare
  wynik number(10,0);
begin
  wynik := fun('923154');
  dbms_output.put_line(wynik);
end; 

Czy ktoś wie w czym jest problem?

0

nie jest to możliwe przy podanym przykładzie. Chcesz pomocy to daj całą funkcję
BTW Oracle 9i to już prawie 15 lat ma

0

Napisałem przecież, że to jest cała funkcja. Dla mnie to też nie jet możliwe, ale wynik temu zaprzecza.

0

wobec tego JEST TO NIEMOŻLIWE - błąd jest gdzie indziej

0

Błąd musi być na etapie przekazania parametru, bo jeżeli dodam w kodzie **wparametr **, który zastąpi mi parametr z funkcji to jest OK

FUNCTION fun(kod varchar2) RETURN NUMBER
IS
  wynik NUMBER(10,0) := 0;
  wparametr varchar2(6) := '923154';
BEGIN
  SELECT a.wartosc INTO wynik
  FROM TabelaB b 
  JOIN TabelaA ON a.kod = b.a_kod
  WHERE b.a_kod = wparametr;
  dbms_output.put_line('f-> ' || wynik);
  RETURN wynik;
END;

Czy możliwe by błąd w funkcji powodowany był przez porównywanie typów varchar2 (byte/char)?

0

Definiując pole typu Byte(6) informujesz bazę, że możesz tam przechowywać coś co posiada maksymalnie 6 bajtów co niekoniecznie przełoży się na 6 znaków (bo niektóre znaki - jeśli baza jest w UTF-8 nie da się zapisać na jednym bajcie). Natomiast definiując pole char(6) mówisz bazie, że można tam trzymać 6 znaków bez względu na to ile bajtów to zajmie. Specyfiki 9i nie znam ale nie takie babole w parserze oracla widziałem więc wszystko możliwe, że automatyczna konwersja byte to varchar lub na odwrót powoduje, że coś się krzaczy jak np w przypadku opisanym przez @Shalom http://4programmers.net/Mikroblogi/Tag/exploit

0

Tak wiem o tym, ale zapytanie poza funkcją zwraca co innego. Może rzeczywiście jest babol w oracle.

0

Chociaż wywołanie

alter table TabelaA modify kod varchar2(6 byte);

nic nie zmieniło w temacie zwracanego wyniku.

0

Możesz to jeszcze sprawdzić w ten sposób, że przygotujesz sobie identyczny przykład z identycznymi danymi na http://sqlfiddle.com/ i zobaczysz czy daje te same efekty co u Ciebie.

0

Tak to jest krążyć wokół czegoś i nie widzieć. Zmieniłem nazwę parametru funkcji na inny niż każda z dostępnych nazw z kolumn w obu tabelach i jest OK

1 użytkowników online, w tym zalogowanych: 0, gości: 1