Avatar billede dakinenexus Nybegynder
26. marts 2001 - 14:24 Der er 12 kommentarer og
3 løsninger

Mangler funktion i PL/SQL

Hej.

Jeg skal bruge en funktion i PL/SQL, som jeg ikke ved hvordan man gør rent kodemæssigt. Hvis det da overhovedet kan lade sig gøre. Nu spørger jeg jer andre. (Jeg arbejder med Oracle Enterprise 8.1.5 på Unix).

Ok. Jeg skal have lavet en PL/SQL funktion, hvori der indgår en SELECT statment, der henter nogle timepriser, som senere skal gange et antal timer.Timepriserne ligger i en tabel kaldt for \'Timepris\'. Der er forskellige timepriser for forskellige kapaciteter.

Statmenten ser ud som følgende:
---------------------------------------------
SELECT Kapacitetbetegnelse,(lon + overhead)
  FROM timepris
  WHERE startaar = \'2001\'
  AND
  (Kapacitetbetegnelse = \'MK\'
    OR Kapacitetbetegnelse = \'MM\'
    OR Kapacitetbetegnelse = \'HS\'
    OR Kapacitetbetegnelse = \'LE\'
    OR Kapacitetbetegnelse = \'KU\'
    OR Kapacitetbetegnelse = \'SW\'
    OR Kapacitetbetegnelse = \'IK\'
  )
  ORDER BY Kapacitetbetegnelse;
---------------------------------------------
Der fremkommer følgende udtræk.


KA (LON+OVERH
-- ----------
HS        370
IK        370
KU        495
LE        271
MK        395
MM        370
SW        370
7 rows selected.

Det jeg så i princippet har brug for er, at jeg skal have udført følgende i PL/SQL:

HS_timepris * antal_HS_timer:
IK_timepris * antal_IK_timer og osv.

Hvordan kan jeg gøre det? Jeg kunne splitte den på en statment for hver udtræk, men det må kunne gøres i en og samme statment.
Jeg tænke på, om man f.eks kan overfører resultaterne til variabler, som senere kunne bruges.

Jeg kender godt SELECT field INTO field_var. Men her har jeg jo 7 resultater. Alle med forskellige navne.

Er der nogle der kan følge mig?
Der er 50 point på forhånd.

Henrik
Avatar billede Slettet bruger
26. marts 2001 - 14:30 #1
Hvor kommer \'antal_HS_timer\' fra?
Avatar billede pgroen Nybegynder
26. marts 2001 - 14:33 #2
Prøv med:

SELECT Kapacitetbetegnelse,timepris * (lon + overhead)
                        FROM timepris
                        WHERE startaar = \'2001\'
                        AND  Kapacitetbetegnelse = \'MK\'
UNION
SELECT Kapacitetbetegnelse,timepris * (lon + overhead)
                        FROM timepris
                        WHERE startaar = \'2001\'
                        AND  Kapacitetbetegnelse = \'MM\'
.
.
.
OSV...
.
.
.
                        ORDER BY Kapacitetbetegnelse;
Avatar billede holdam Nybegynder
26. marts 2001 - 14:34 #3
Hvis jeg ellers kan følge dig, må svaret være noget i retning af følgende:

SELECT timepris.Kapacitetbetegnelse, (timepris.lon + timepris.overhead), (timepris.lon+timepris.overhead)*timer.antal_timer
  FROM timepris, timer
  WHERE timepris.startaar = \'2001\'
    AND (timepris.Kapacitetbetegnelse IN (\'MK\', \'MM\', \'HS\', \'LE\', \'KU\' \'SW\', \'IK\')
    AND timepris.Kapacitetbetegnelse=timer.Kapacitetbetegnelse
  )
ORDER BY timepris.Kapacitetbetegnelse;
Avatar billede pgroen Nybegynder
26. marts 2001 - 14:48 #4
Hov, jeg havde vist hovedet under armen et øjeblik...

holdams løsning er jo en hel del mere korrekt og \'by the book\'.

Avatar billede holdam Nybegynder
26. marts 2001 - 14:51 #5
- den sidste parentes røg lige en linie for langt ned; det skal se således ud:
...
    AND (timepris.Kapacitetbetegnelse IN (\'MK\', \'MM\', \'HS\', \'LE\', \'KU\' \'SW\', \'IK\'))
    AND timepris.Kapacitetbetegnelse=timer.Kapacitetbetegnelse
Avatar billede dakinenexus Nybegynder
26. marts 2001 - 14:53 #6
Antal HS_timer er blot et tal gemt i en NUMBER variable. Jeg har så en variable for hver kapacitet. Dvs. MKvar, MMvar. De indeholder forbruget, som skal ganges med prisen for hvad én time koster.

Svaret fra dig Holdam er måske nok muligt. Skal have prøvet det af. Jeg kan altså simpelthen gange timeforbruget direkte med prisen inde i SELECT stantmenten. !! Hmmnn.
Avatar billede Slettet bruger
26. marts 2001 - 14:58 #7
Lav en lille tabel TIMER, med poster
(kapacitetsbetegnelse, antal_timer)

og lav join:

SELECT Kapacitetbetegnelse,(lon + overhead),(lon + overhead)*antal_timer
  FROM timepris, timer
  WHERE startaar = \'2001\'
  AND timepris.Kapacitetbetegnelse = timer.kapacitetsbetegnelse
  ORDER BY Kapacitetbetegnelse;
Avatar billede dakinenexus Nybegynder
26. marts 2001 - 15:14 #8
Jeg ønsker ikke at oprette en ny tabel til beregningen. For det første ligger de brugte ressourcer og timerpriserne ikke engang i samme database.
Forbruget fremkommer ved at rende en stykliste igennem i en løkke, indtil der ikke er flere. Derefter vil jeg gange med timeprisen for den pågældende kapacitet.

I princippet noget med:

SELECT MKtimepris INTO varMKPris, MMtimepris INTO varMMPris.......
FROM...........
WHERE........osv.

SamletMK := MKforbrug * varMKpris;
SamletMM := MMforbrug * varMMpris;
....
....
Jeg ved udemærket, at man ikke kan udfører den ovenstående statment, men blot som et tankeeksempel, der kan vise hvad jeg mener.
Avatar billede pgroen Nybegynder
26. marts 2001 - 15:22 #9
OK, jamen så er vi inde på noget i stil med:

SELECT Kapacitetbetegnelse, SUM((lon + overhead)*antal_timer)
                          FROM timepris, timer
                          WHERE startaar = \'2001\'
                          AND timepris.Kapacitetbetegnelse = timer.kapacitetsbetegnelse
GROUP BY timepris.kapacitetsbetegnelse;

Avatar billede dakinenexus Nybegynder
26. marts 2001 - 15:32 #10
pgroen:
Se det ser mere fornuftigt ud ! MEN.........

Jeg har ikke en tabel, det hedder timer. Forbruget ligger blot i NUMBER variabler, men det er en biting.
Men tager din statment højde for, at det er MKprisen der ganges med MKforbruget.
MMprisen ganges med MMforbruget.
HSprisen ganges med HSforbruget.

(Det gør den vel egentlig ikke set med mine øjne).

\'SUM((lon + overhead)*antal_timer\' Denne skal jo udføres syv gange. En gang for hver kapacitet.

Men i er bestemt indepå noget af de rigtige. :-)
Den er lidt kringlet. Det indrømmet jeg, men det må kunne lade sig gøre.

Jeg kan ikke helt gennemskue din statment holdam. Hvad den IN gør! Holder den kapaciteterne adskilt fra hinanden?


Avatar billede Slettet bruger
26. marts 2001 - 15:39 #11
Hvad med en funktion?

create or replace function get_timer(kapacitet in varchar2) return number is
  returnval number;
begin
  for r in (SELECT lon + overhead val
  FROM timepris
  WHERE startaar = \'2001\'
  AND Kapacitetbetegnelse = kapacitet) loop
    returnval:=r.val;
  end loop;
return returnval;
end;

Så kan du sige:

SamletMK := MKforbrug * get_timer(\'MK\');
Avatar billede pgroen Nybegynder
26. marts 2001 - 15:41 #12
Ja til begge dele;

Du får 7 rækker som svar, med den samlede sum for hver kapacitet,

Og holdams IN gør præcis det samme som din egen OR - blot mere elegant
(og formentlig mere effektivt, så\'n rent performancemæssigt)
Avatar billede dakinenexus Nybegynder
27. marts 2001 - 08:32 #13
Ok. Jeg tror jeg har noget matriale at komme videre med nu. Jeg skal have lavet min function og have prøvet det af.
Måske vender jeg tilbage, men i har alle gjort et godt stykke arbejde, så i skal have jeres point.
Jeg går i første omgang efter holdam\'s løsning.

Og en kommentar til joern_h. Jo. Planen har heletiden været at lave det i en funktion. Jeg ved også godt, at jeg kunne rende igennem en løkke, og dermed køre syv SELECT statments, men det har på en eller anden måde gået på at gøre det i én statment.


Men mange tak for hjælpen til jer alle.

Mvh.
DaKineNexus
Avatar billede Slettet bruger
27. marts 2001 - 14:08 #14
Hej DakineNexus

Jeg kører IKKE gennem en løkke!

Jeg bruger et for loop, der kører een gang. På den måde slipper jeg for at definere, åbne og lukke en cursor eksplicit.
Avatar billede dakinenexus Nybegynder
28. marts 2001 - 08:46 #15
Til joern_h

Det må du meget undskylde. Det var absolut ikke meningen at fornærme dig :)
Så skulle jeg måske kigge lidt nærmere på din også.
Du bruger godt nok også noget med \'returnval\' som jeg ikke rigtigt kender. Det har jeg åbenbart ikke bemærket i første omgang. Der var jeg måske lidt for hurtig.

Tak
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester