Avatar billede miqe Nybegynder
20. maj 2007 - 15:41 Der er 3 kommentarer og
2 løsninger

Dynamisk retur-type i funktion

Kan det lade sig gøre at have en dynamisk returtype i en funktion?

Jeg har en funktion, hvor jeg gerne vil kunne returnere et DATE-element eller en tekst afhængig diverse parametre.

Med andre ord. Kan man i funktionskaldet fortælle funktionen hvilket returtype man ønsker tilbage?
Avatar billede pgroen Nybegynder
20. maj 2007 - 15:59 #1
Hvis du benytter dig af pakke-procedurer i stedet (Hvilket vist også ville være 'pænere'), kan du overloade dine parametre

se:
http://download-uk.oracle.com/docs/cd/B10501_01/appdev.920/a96624/09_packs.htm#4937
Avatar billede miqe Nybegynder
20. maj 2007 - 16:18 #2
Har seriøst overvejet at overloade, men da store dele af koden vil gå igen, virker det ikke helt optimalt.
Desuden kan man ikke overloade, hvis det kun er returtypen, der er forskellig.

Kan være jeg bare skal parameteroverføre nogle variable IN OUT, som jeg så ikke nødvendigvis vil opdatere.

Findes der en smartere måde at emulere en variabel output-type?
Avatar billede Slettet bruger
20. maj 2007 - 16:44 #3
En funktion er defineret på sine argumenter.

Hvis du kører følgende, vil du oprette en funktion.

select * from user_procedures;
create or replace
function getValue (pType in varchar2) return varchar2
is
begin
  return 'varchar2 værdi';
end;
/

Hvis du derefter kører følgende, vil den første funktion blive erstattet med den nye fordi navnet på funktionen er den samme og argumentlisten har de samme typer (een varchar2).

create or replace
function getValue (pType in varchar2) return date
is
begin
  return date '2007-05-20';
end;
/

Du kan selv se efter i USER_PROCEDURES, at den første bliver erstattet med den anden.
Du kan se detailoplysninger i USER_ARGUMENTS. Bla. kan du se, at returværdien er en DATE (sekvensnr. 0 og intet ARGUMENT_NAME).

Det kan derfor blive svært at lave, det du vil, med en funktion. Men hvad vil du returnere i? Allerede når du skriver v := .... har du et problem, for hvad type skal v have?

En anden mulighed: Lav en procedure med OUT-parametre. Så kan du efterfølgende læse den relevant af parametrene. I det følgende eksempel er der kun værdi i enten pString eller pdate. Det er input pValueType, der afgør, hvilken outværdi, man skal bruge.

CREATE OR REPLACE
PROCEDURE getvalue(
  pvaluetype IN VARCHAR2,  pstring OUT VARCHAR2,  pdate OUT DATE) IS
BEGIN
  CASE pvaluetype
  WHEN 'varchar2' THEN
  BEGIN
    pstring := 'Streng';
    pdate := NULL;
  END;
  ELSE
  BEGIN
    pdate := sysdate;
    pstring := NULL;
  END;
  END
  CASE;
END;
/

DECLARE
  vdate DATE;
  vstr VARCHAR2(200);
BEGIN
  -- gi mig en dato
  getvalue('varchar2',  vstr,  vdate);
  DBMS_OUTPUT.PUT_LINE('str, dato = ' || vstr || ', ' || vdate);
  -- gi en dato
  getvalue('andet',  vstr,  vdate);
  DBMS_OUTPUT.PUT_LINE('str, dato = ' || vstr || ', ' || vdate);
END;
/
Avatar billede miqe Nybegynder
17. juni 2007 - 00:48 #4
Man kan ikke overloade en funktion hvor alene returtypen adskilder sig og derved mister jeg nytteværdien af en funktion.
Havde en idé om at have en funktion/procedure, med en række forskellige konverteringsmuligheder. Har en idé om at det muligvis kan gøres uden at overloade.

Svaret på spørgsmålet som jeg har stillet det må være, at det ikke kan lade sig gøre at lave en dynamisk angivelse af returtypen for et element, med mindre man overloader en eller flere parametre i funktionskaldet.

Kan selvfølgelig nøjes med at smide parametre ind, der gerne må overskrives og dermed bruge IN OUT.
Dermed kan stregen være null, når man vil bruge date-elementet.
Output vil derved overskrive både streng og date-element ligemeget hvad man putter ind.
Avatar billede Slettet bruger
17. juni 2007 - 12:42 #5
miqe: Du har fuldstændig ret. I stedet for at bruge IN OUT som returparameters værdi kan du nøjes med OUT, da den jo ikke skal læses af proceduren, kun bruges til at returnere en værdi. Hvis du bruger IN OUT, skal PL/SQL kopiere den eksisterende værdi af parameteren med sig. Du kan undgå dette ved at bruge IN OUT NOCOPY som medfører at den kaldte procedure referer direkte til variablen, ikke til en kopi, der så skal kopieres med frem og tilbage. Ulempen ved IN OUT NOCOPY er at man ikke kan være sikker på den værdi, man får tilbage, hvis procedurekaldet af en eller anden grund fejlede.
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