Wyniki procedury zwracają błędne dane

Odpowiedz Nowy wątek
2019-10-17 12:48

Rejestracja: 8 lat temu

Ostatnio: 3 tygodnie temu

0

Witam.

Jestem początkujący w pisaniu procedur. Napisałem procedurę która zwraca mi dane na podstawie zakresów dat. Wartości obrotu pokazują jednak zera mimo że prawdziwy obrót jest zdecydowanie wyższy. Nie do końca jednak wiem co zrobiłem źle. Stąd moja prośba o pomoc.

Moja procedura :

create or replace PROCEDURE Marza_II_PROCEDURE(FirstDateOpen DATE,FirstDateClose DATE
,SecondDateOpen DATE ,SecondDateClose DATE
)
as

BEGIN
Begin
EXECUTE IMMEDIATE 'DROP TABLE MARZA_REPORT' ;
EXCEPTION
   WHEN OTHERS THEN
      IF SQLCODE != -942 THEN
         RAISE;
      END IF;
    End;
    COMMIT;
EXECUTE IMMEDIATE 'CREATE TABLE MARZA_REPORT AS
    select BH,ODBIORCA,KANAL_SPRZEDAZY,SEGMENT2018,SEGMENT2019,
SUM(CASE WHEN MIESIAC BETWEEN '|| FirstDateOpen ||' and '||FirstDateClose ||' then OBROT else 0 end) OBROT1,
SUM(CASE WHEN MIESIAC BETWEEN '|| SecondDateOpen ||' and '||SecondDateClose ||' then OBROT else 0 end) OBROT2
from dws1.marza_netto

WHERE MIESIAC >= '|| SecondDateOpen ||' 
AND ODBIORCA IN (''0001006834'',''0001024402'',''0001000043'')
GROUP BY BH,ODBIORCA,KANAL_SPRZEDAZY,SEGMENT2018,SEGMENT2019';

END;

Wywołuję to :

Begin
Marza_II_PROCEDURE(to_date('20190101','yyyymmdd'),to_date('20190201','yyyymmdd'),to_date('20180101','yyyymmdd'),to_date('20180201','yyyymmdd'));
End;

Jednak dane które są zwracane do tablicy są błędne.

Pozostało 580 znaków

2019-10-17 14:59

Rejestracja: 4 lata temu

Ostatnio: 24 minuty temu

0

W tej Twojej procedurze:

  • COMMIT; po DROP jest niepotrzebny, bo w Oracle DDLe powodują niejawnego commita (wiąże się to z zatwierdzeniem zmian w słowniku systemowym)
  • Zamiast kleić te zapytanie i ginąć w nadmiarze ', można użyć techniki "escape single quote":
v_statement := q'[  select 1 from dual where 'a'='a' ]';
  • Zamiast doklejać wartości użyj zmiennych w zapytaniu i przekaż wartości:
v_statement := q'[ select 1 from dual where 1=:jeden and 2=:dwa ]'
EXECUTE IMMEDIATE v_statement USING v_value_a, v_value_b; 
  • WHERE MIESIAC >= '|| SecondDateOpen ||', nie wiem co siedzi w kolumnie MIESIAC, ale nazwa wskazuje, że miesiąc, a nie jakaś data. Przekazujesz to_date('20180101','yyyymmdd').
edytowany 1x, ostatnio: yarel, 2019-10-17 15:00

Pozostało 580 znaków

2019-10-17 16:30

Rejestracja: 7 lat temu

Ostatnio: 2 godziny temu

0

a ja mam pytanie dlaczego w ogóle używasz EXECUTE IMMEDIATE?


Chcesz pomocy - pokaż kod - abrakadabra źle działa z techniką.

Pozostało 580 znaków

2019-10-17 23:29

Rejestracja: 1 rok temu

Ostatnio: 16 godzin temu

0
  1. Unikamy tworzenia/usuwania obiektów wewnątrz procedur - możesz zrobić zwykły DELETE
    albo ewentualnie TRUNCATE, jeśli zawartość tabeli jest bardzo duża

  2. Błąd zapewne polega na porównywaniu pola MIESIAC z datą, co z tego wyjdzie to trudno powiedzieć.
    Pokaż jak wygląda definicja tabeli i przykładowe wartości tego pola - czy jest to np. 11 czy też 201811?
    Albo '2018-11'?

Poza tym w SUM masz ten sam problem:

CASE WHEN MIESIAC BETWEEN '|| FirstDateOpen ||' and '||FirstDateClose ||' then OBROT else 0 end

Tak jak w matematyce, musisz to sprowadzić do wspólnego mianownika. Musisz porównywać pola o tych samych typach,
czyli albo MIESIAC konwertujesz na datę albo daty przerabiasz tak, żeby pasowały do formatu pola MIESIAC.

  1. Dynamiczny SQL jest tu zbędny - zamień CREATE TABLE na INSERT ... SELECT ...

Pozostało 580 znaków

Odpowiedz

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