Brukerdefinert funksjon

En **brukerdefinert funksjon** er en funksjon skrevet av brukeren av et program. Begrepet brukes gjerne i forbindelser hvor den vanlige antakelsen er at de nødvendige funksjonene allerede er innebygd i programmet. Brukerdefinerte funksjoner skrives som regel på grunn av at programmøren har spesielle behov.

## BASIC-språket
I noen gamle implementeringer av programmeringsspråket BASIC lages brukerdefinerte funksjoner definert ved hjelp syntaksen "DEF&nbsp;FN". Nyere dialekter av BASIC har blitt påvirket av det strukturerte programmeringsparadigmet hvor enten det meste eller alt av kode er skrevet med brukerdefinerte funksjoner eller prosedyrer, og konseptet blir dermed praktisk talt overflødig.

## COBOL-språket
I programmeringsspråket COBOL er en brukerdefinert funksjon en entitet som defineres av brukeren ved å spesifisere et FUNCTION ID-avsnitt. En brukerdefinert funksjon må returnere en verdi ved å spesifisere RETURNING-frasen til prosedyrens divisjonshode, og disse kalles med funksjonsidentifikator-syntaksen. Standarden ISO/IEC 1989:2014 Programming Language COBOL har flere detaljer.

Fra og med 2022 mai har kompilatoren IBM Enterprise COBOL for z/OS 6.4 (IBM COBOL) støtte for brukerdefinerte funksjoner.

## Databaser
I databasehåndteringssystem for relasjonsdatabaser (RDMBS-er) gir brukerdefinerte funksjoner en mekanisme for å utvide funksjonaliteten til en databasetjener ved å legge til en funksjon som kan evalueres i standarduttrykk i spørrespråk (vanligvis SQL). SQL-standarden skiller mellom skalare og tabulare funksjoner. En skalarfunksjon returnerer bare én enkelt verdi (eller NULL), mens en tabellfunksjon returnerer en (relasjonell) tabell som består av ingen eller flere rader, og hvor hver rad har én eller flere kolonner.

Brukerdefinerte funksjoner i SQL deklareres ved hjelp av `CREATE FUNCTION`-uttrykket. For eksempel kan en brukerdefinert funksjon som konverterer celsius til fahrenheit (en temperaturskala som brukes I USA) deklareres slik:
```sql
CREATE FUNCTION dbo.CtoF(Celsius FLOAT)
 RETURNS FLOAT
 RETURN (Celsius * 1.8) + 32
```
Når en brukerdefinert funksjon er opprettet kan den brukes i uttrykk i SQL-setninger. For eksempel kan den kalles de fleste steder hvor andre innebygde funksjoner er tillatt. Dette inkluderer SELECT-uttrykk, hvor funksjonen kan brukes mot data lagret i tabeller i databasen. Ved slik bruk blir funksjonen konseptuelt evaluert en gang per rad. For eksempel kan man anta en tabell som heter  med én rad for hvert kjente grunnstoff. Tabellen har en kolonne som heter BoilingPoint for kokepunktet til hvert element oppgitt i celsius. Den følgende spørringen:
```sql
SELECT Name, CtoF(BoilingPoint)
 FROM Elements
```
vil returnere navn og kokepunkt for hver rad. Den kaller den brukerdefinerte `CtoF`-funksjonen som deklarert ovenfor, og vil konvertere verdien i kolonnen til en verdi i fahrenheit.

Hver brukerdefinerte funksjon har visse egenskaper eller karakteristikker. SQL-standarden definerer følgende egenskaper:

* Språk: Definerer programmeringsspråket der den brukerdefinerte funksjonen er implementert. Eksempler inkluderer SQL, C, C# og Java.
* Parameterstil: Definerer konvensjonene som brukes til å overføre funksjonsparametrene og resultatene mellom implementeringen av funksjonen og databasesystemet (gjelder bare hvis språket ikke er SQL).
* Spesifikt navn: Et navn på funksjonen som er unikt i databasen. Merk at funksjonsnavnet ikke trenger å være unikt med tanke på overdefinerte funksjoner. Noen SQL-implementeringer krever at funksjonsnavn er unike i en database, og overbelastede funksjoner er ikke tillatt.
* Determinisme: Angir om funksjonen er deterministisk eller ikke. Determinisme-karakteristikken har innflytelse på spørreoptimering når en SQL-setning kompileres.
* SQL-datatilgang: Forteller databasestyringssystemet om funksjonen ikke inneholder noen SQL-setninger (NO SQL), eller inneholder SQL-setninger men ikke får tilgang til noen tabeller eller visninger (CONTAINS SQL), eller leser data fra tabeller eller visninger (READS SQL DATA), eller faktisk endrer data i databasen (MODIFIES SQL DATA).

### Sammenlignet med lagrede prosedyrer
Brukerdefinerte funksjoner må ikke forveksles med lagrede prosedyrer. En lagret prosedyre lar brukeren gruppere en mengde av SQL-kommandoer, og de kan motta parametere og utføre SQL-setninger som avhenger av disse parametrene. En prosedyre er ikke et uttrykk, og (lagrede prosedyrer) kan derfor ikke brukes som brukerdefinerte funksjoner.

### Andre språk
Noen databasestyringssystemer tillater at det opprettes brukerdefinerte funksjoner på andre språk enn SQL. For eksempel lar Microsoft SQL Server brukeren bruke .NET-språk inkludert C# for dette formålet. DB2 og Oracle støtter brukerdefinerte funksjoner skrevet i C eller Java.

#### SQL Server 2000
I Microsoft SQL Server 2000 er det 3 typer brukerdefinerte funksjoner: Skalarfunksjoner, innebygde tabellfunksjoner og fleruttrykks tabellfunksjoner.

* Skalarfunksjoner returnerer en enkelt dataverdi (ikke en tabell) med RETURNS-klausulen. De kan bruke alle skalare datatyper, med unntak av tidsstempel og brukerdefinerte datatyper.
* Innebygde tabellfunksjoner returnerer resultatmengden av en enkelt SELECT-uttrykk/setning
* Fleruttrykks tabellfunksjoner returnerer en tabell som har blitt bygget med mange TRANSACT-SQL-uttrykk/setninger

Brukerdefinerte funksjoner kan kalles fra en spørring lik som for innebygde funksjoner som OBJECT_ID(), LEN() og DATEDIFF(), eller kan kjøres via en EXECUTE-setning som lagrede prosedyrer.

På Microsoft SQL Server 2000 kan ytelsen til tabellfunksjoner som "pakker" en visning være mye raskere enn selve visningen. Deb følgende funksjonen MyFunction er et eksempel på en funksjonsinnpakning som går raskere enn den underliggende visningen MyView:
```tsql
CREATE FUNCTION MyFunction()
  RETURNS @Tbl TABLE 
  (
    StudentID       VARCHAR(255),
    SAS_StudentInstancesID INT,
    Label         VARCHAR(255),
    Value         MONEY,
    CMN_PersonsID     INT
  )
AS
BEGIN
  INSERT @Tbl
  (
    StudentID,
    SAS_StudentInstancesID,
    Label,
    Value,
    CMN_PersonsID
  )
  SELECT 
    StudentID,
    SAS_StudentInstancesID,
    Label,
    Value,
    CMN_PersonsID
  FROM MyView -- where MyView selects (with joins) the same columns from large table(s)

  RETURN
END
```
På Microsoft SQL Server 2005 er derimot resultatet av den samme kodeutførelsen motsatte: Visningen utføres raskere enn funksjonsinnpakningen.

Brukerdefinerte funksjoner i Microsoft SQL er underrutiner laget av en eller flere Transact-SQL-setninger som kan brukes til å innkapsle kode for gjenbruk.

* Den tar ingen eller flere argumenter og evaluerer en returverdi
* Inneholder både kontrollflyt- og DML-uttrykk som ligner på lagrede prosedyrer
* Tillater ikke endringer i globale øktstatuser, eksempelvis endringer i databaseressurser eller eksterne ressurser som en fil eller et nettverk
* Støtter ikke utputtparametre
* DEFAULT-nøkkelordet må spesifiseres for å overføre standardverdiern til parameteren
* Feil i brukerdefinerte funksjoner får brukerdefinerte funksjoner til å avbrytes, som igjen avbryter uttrykket som kalte den brukerdefinerte funksjonen

```tsql
CREATE FUNCTION CubicVolume
-- Input dimensions in centimeters
(
  @CubeLength decimal(4,1), 
  @CubeWidth decimal(4,1),
  @CubeHeight decimal(4,1)
)
  RETURNS decimal(12,3)
AS
BEGIN
 RETURN(@CubeLength * @CubeWidth * @CubeHeight)
END
```
Datatyper som støttes i Microsoft SQL Server 2000:

* Som en midlertidig tabell som brukes til å lagre resultater
* Mest brukt til å definere midlertidige variabler av type (tabell) og returverdien til en brukerdefinerte funksjon.
* Omfanget er begrenset til funksjon, lagret prosedyre eller satsen der den er definert
* Tildelingsoperasjon er ikke tillatt mellom (tabell)variabler
* Kan brukes i SELECT, INSERT, UPDATE og DELETE
* CREATE FUNCTION brukes for å opprette en brukerdefinert funksjon
* ALTER FUNCTION brukes for å endre egenskapene til en brukerdefinert funksjon
* DROP FUNCTION brukes for å fjerne en brukerdefinert funksjon

#### Apache Hive
Apache Hive definerer, i tillegg til de vanlige brukerdefinerte funksjoner, også brukerdefinerte *aggregerte* funksjoner (UDAF) og *tabellgenererende* funksjoner (UDTF). Hive gjør det mulig for utviklere å lage sine egne tilpassede funksjoner med Java.

#### Apache Doris
Apache Doris, en åpent kildekodet sanntidsanalytisk database, lar eksterne brukere bidra med sine egne brukerdefinerte funksjoner til databasen.

## Referanser