Teknologi, AI og forretning er i centrum på Computerworlds Cloud og AI Festival i København d. 18. og 19. september. Se hele programmet for den store konference om strategisk brug af Cloud og AI på: www.cloud-festival.dk
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?
Synes godt om
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; /
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.
Synes godt om
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.
Synes godt om
Ny brugerNybegynder
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.