CREATE FUNCTION (SQL och Python)
Gäller för: Databricks SQL Databricks Runtime
Skapar en SQL-skalär- eller tabellfunktion som tar en uppsättning argument och returnerar ett skalärt värde eller en uppsättning rader.
Gäller för: Databricks SQL Databricks Runtime 13.3 LTS och senare
Skapar en Python-skalär funktion som tar en uppsättning argument och returnerar ett skalärt värde.
Python-UDF:er kräver Unity Catalog på serverlösa eller pro SQL-lager eller ett delat eller enstaka Unity Catalog-kluster.
Gäller för: Databricks SQL Databricks Runtime 14.1 och senare
Förutom anrop av positionsparametrar kan du även anropa SQL och Python UDF med hjälp av namngivna parameteranrop.
Syntax
CREATE [OR REPLACE] [TEMPORARY] FUNCTION [IF NOT EXISTS]
function_name ( [ function_parameter [, ...] ] )
{ [ RETURNS data_type ] |
RETURNS TABLE [ ( column_spec [, ...]) ] }
[ characteristic [...] ]
{ AS dollar_quoted_string | RETURN { expression | query } }
function_parameter
parameter_name data_type [DEFAULT default_expression] [COMMENT parameter_comment]
column_spec
column_name data_type [COMMENT column_comment]
characteristic
{ LANGUAGE { SQL | PYTHON } |
[NOT] DETERMINISTIC |
COMMENT function_comment |
[CONTAINS SQL | READS SQL DATA] }
Parametrar
ELLER ERSÄTT
Om det anges ersätts funktionen med samma namn och signatur (antal parametrar och parametertyper). Du kan inte ersätta en befintlig funktion med en annan signatur. Detta är främst användbart för att uppdatera funktionstexten och funktionens returtyp. Du kan inte ange den här parametern med
IF NOT EXISTS
.TEMPORÄR
Omfånget för funktionen som skapas. När du anger
TEMPORARY
är den skapade funktionen giltig och synlig i den aktuella sessionen. Ingen beständig post görs i katalogen.OM INTE FINNS
Om det anges skapar funktionen endast när den inte finns. Det går att skapa funktionen (inget fel utlöses) om den angivna funktionen redan finns i systemet. Du kan inte ange den här parametern med
OR REPLACE
.-
Ett namn på funktionen. För en permanent funktion kan du eventuellt kvalificera funktionsnamnet med ett schemanamn. Om namnet inte är kvalificerat skapas den permanenta funktionen i det aktuella schemat.
function_parameter
Anger en parameter för funktionen.
-
Parameternamnet måste vara unikt i funktionen.
-
Alla datatyper som stöds. För Python
data_type
skickas till en Python-datatyp enligt den här språkmappningen. STANDARD default_expression
Gäller för: Databricks SQL Databricks Runtime 10.4 LTS och senare
Ett valfritt standardvärde som ska användas när ett funktionsanrop inte tilldelar ett argument till parametern.
default_expression
måste vara gjutbar tilldata_type
. Uttrycket får inte referera till en annan parameter eller innehålla en underfråga.När du anger ett standardvärde för en parameter måste alla följande parametrar också ha ett standardvärde.
DEFAULT
stöds endast förLANGUAGE SQL
.KOMMENTAR
En valfri beskrivning av parametern.
comment
måste vara enSTRING
literal.
-
RETURNERAR data_type
Den skalära funktionens returdatatyp. För Python-UDF:er måste returvärden exakt matcha datatypen enligt vad som anges i
data_type
. Annars misslyckas funktionen för att förhindra oväntade typkonverteringar.För SQL UDF är den här satsen valfri. Datatypen härleds från funktionstexten om den inte tillhandahålls.
RETURNERAR TABELL [ (column_spec [,...] ) ]
Den här satsen markerar funktionen som en tabellfunktion. Du kan också ange signaturen för resultatet av tabellfunktionen. Om ingen column_spec anges härleds den från brödtexten i SQL UDF.
RETURNS TABLE
stöds endast förLANGUAGE SQL
.-
Kolumnnamnet måste vara unikt i signaturen.
-
Alla datatyper som stöds.
KOMMENTAR column_comment
En valfri beskrivning av kolumnen.
comment
måste vara enSTRING
literal.
-
RETUR { uttrycksfråga | }
Funktionens brödtext. För en skalär funktion kan det antingen vara en fråga eller ett uttryck. För en tabellfunktion kan det bara vara en fråga. Uttrycket får inte innehålla:
- Mängdfunktioner
- Fönsterfunktioner
- Rankningsfunktioner
- Radproduktionsfunktioner som exploderar
I brödtexten i funktionen kan du referera till parametern med dess okvalificerade namn eller genom att kvalificera parametern med funktionsnamnet.
AS-dollar_quoted_definition
dollar_quoted_definition
är Python-funktionenbody
omgiven av två matchande$[tag]$body$[tag]$
.tag
kan vara en tom sträng.Exempel:
$$ return “Hello world” $$ $py$ return "Hello World" $py$
kännetecken
Alla egenskapssatser är valfria. Du kan ange valfritt antal av dem i valfri ordning, men du kan bara ange varje sats en gång.
LANGUAGE SQL eller LANGUAGE PYTHON
Språket för funktionsimplementeringen.
[NOT] DETERMINISTISK
Om funktionen är deterministisk. En funktion är deterministisk när den bara returnerar ett resultat för en viss uppsättning argument. Du kan markera en funktion som
DETERMINISTIC
när dess brödtext inte är och vice versa. En orsak till detta kan vara att uppmuntra eller avskräcka från frågeoptimeringar, till exempel konstant vikning eller cachelagring av frågor. Om du inte anger det här alternativet härleds det från funktionstexten.KOMMENTAR function_comment
En kommentar för funktionen.
function_comment
måste vara Strängliteral.INNEHÅLLER SQL - eller READS SQL DATA
Om en funktion läser data direkt eller indirekt från en tabell eller en vy. När funktionen läser SQL-data kan du inte ange
CONTAINS SQL
. Om du inte anger någon av satserna härleds egenskapen från funktionstexten.
Bibliotek som stöds i Python UDF:er
Om du vill använda beroenden använder du import <package>
i funktionstexten. Se till exempel följande:
CREATE FUNCTION […]
AS $$
import json
[... (rest of function definition)]
$$
Beroenden är begränsade till python-standardbiblioteket och följande bibliotek:
Paket | Version |
---|---|
blekmedel | 4.0.0 |
chardet | 4.0.0 |
charset-normalizer | 2.0.4 |
defusedxml | 0.7.1 |
googleapis-common-protos | 1.56.4 |
grpcio | 1.47.0 |
grpcio-status | 1.47.0 |
jmespath | 0.10.0 |
joblib | 1.1.0 |
numpy | 1.20.3 |
emballage | 21,3 |
Pandas | 1.3.4 |
Patsy | 0.5.2 |
protobuf | 4.21.5 |
pyarrow | 7.0.0 |
pyparsing | 3.0.9 |
python-dateutil | 2.8.2 |
pytz | 2021.3 |
scikit-learn | 0.24.2” |
scipy | 1.7.1” |
setuptools | 65.2.0 |
sex | 1.16.0 |
threadpoolctl | 3.1.0 |
webencodings | 0.5.1 |
användaragenter | 2.2.0 |
kryptografi | 38.0.4 |
Exempel
- Skapa och använda en SQL-skalär funktion
- Skapa och använda en funktion som använder DEFAULT
- Skapa en SQL-tabellfunktion
- Ersätt en SQL-funktion
- Beskriva en SQL-funktion
- Skapa Python-funktioner
Skapa och använda en SQL-skalär funktion
> CREATE VIEW t(c1, c2) AS VALUES (0, 1), (1, 2);
-- Create a temporary function with no parameter.
> CREATE TEMPORARY FUNCTION hello() RETURNS STRING RETURN 'Hello World!';
> SELECT hello();
Hello World!
-- Create a permanent function with parameters.
> CREATE FUNCTION area(x DOUBLE, y DOUBLE) RETURNS DOUBLE RETURN x * y;
-- Use a SQL function in the SELECT clause of a query.
> SELECT area(c1, c2) AS area FROM t;
0.0
2.0
-- Use a SQL function in the WHERE clause of a query.
> SELECT * FROM t WHERE area(c1, c2) > 0;
1 2
-- Compose SQL functions.
> CREATE FUNCTION square(x DOUBLE) RETURNS DOUBLE RETURN area(x, x);
> SELECT c1, square(c1) AS square FROM t;
0 0.0
1 1.0
-- Create a non-deterministic function
> CREATE FUNCTION roll_dice()
RETURNS INT
NOT DETERMINISTIC
CONTAINS SQL
COMMENT 'Roll a single 6 sided die'
RETURN (rand() * 6)::INT + 1;
-- Roll a single 6-sided die
> SELECT roll_dice();
3
Skapa och använda en funktion som använder DEFAULT
-- Extend the function to support variable number of sides and dice.
-- Use defaults to support a variable number of arguments
> DROP FUNCTION roll_dice;
> CREATE FUNCTION roll_dice(num_dice INT DEFAULT 1 COMMENT 'number of dice to roll (Default: 1)',
num_sides INT DEFAULT 6 COMMENT 'number of sides per die (Default: 6)')
RETURNS INT
NOT DETERMINISTIC
CONTAINS SQL
COMMENT 'Roll a number of n-sided dice'
RETURN aggregate(sequence(1, roll_dice.num_dice, 1),
0,
(acc, x) -> (rand() * roll_dice.num_sides)::int,
acc -> acc + roll_dice.num_dice);
-- Roll a single 6-sided die still works
> SELECT roll_dice();
3
-- Roll 3 6-sided dice
> SELECT roll_dice(3);
15
-- Roll 3 10-sided dice
> SELECT roll_dice(3, 10)
21
-- Roll 3 10-sided dice using named parameter invocation
> SELECT roll_dice(10 => num_sides, num_dice => 3)
17
-- Create a SQL function with a scalar subquery.
> CREATE VIEW scores(player, score) AS VALUES (0, 1), (0, 2), (1, 2), (1, 5);
> CREATE FUNCTION avg_score(p INT) RETURNS FLOAT
COMMENT 'get an average score of the player'
RETURN SELECT AVG(score) FROM scores WHERE player = p;
> SELECT c1, avg_score(c1) FROM t;
0 1.5
1 3.5
Skapa en SQL-tabellfunktion
-- Produce all weekdays between two dates
> CREATE FUNCTION weekdays(start DATE, end DATE)
RETURNS TABLE(day_of_week STRING, day DATE)
RETURN SELECT extract(DAYOFWEEK_ISO FROM day), day
FROM (SELECT sequence(weekdays.start, weekdays.end)) AS T(days)
LATERAL VIEW explode(days) AS day
WHERE extract(DAYOFWEEK_ISO FROM day) BETWEEN 1 AND 5;
-- Return all weekdays
> SELECT weekdays.day_of_week, day
FROM weekdays(DATE'2022-01-01', DATE'2022-01-14');
1 2022-01-03
2 2022-01-04
3 2022-01-05
4 2022-01-06
5 2022-01-07
1 2022-01-10
2 2022-01-11
3 2022-01-12
4 2022-01-13
5 2022-01-14
-- Return weekdays for date ranges originating from a LATERAL correlation
> SELECT weekdays.*
FROM VALUES (DATE'2020-01-01'),
(DATE'2021-01-01'),
(DATE'2022-01-01') AS starts(start),
LATERAL weekdays(start, start + INTERVAL '7' DAYS);
3 2020-01-01
4 2020-01-02
5 2020-01-03
1 2020-01-06
2 2020-01-07
3 2020-01-08
5 2021-01-01
1 2021-01-04
2 2021-01-05
3 2021-01-06
4 2021-01-07
5 2021-01-08
1 2022-01-03
2 2022-01-04
3 2022-01-05
4 2022-01-06
5 2022-01-07
Ersätt en SQL-funktion
-- Replace a SQL scalar function.
> CREATE OR REPLACE FUNCTION square(x DOUBLE) RETURNS DOUBLE RETURN x * x;
-- Replace a SQL table function.
> CREATE OR REPLACE FUNCTION getemps(deptno INT)
RETURNS TABLE (name STRING)
RETURN SELECT name FROM employee e WHERE e.deptno = getemps.deptno;
-- Describe a SQL table function.
> DESCRIBE FUNCTION getemps;
Function: default.getemps
Type: TABLE
Input: deptno INT
Returns: id INT
name STRING
Kommentar
Du kan inte ersätta en befintlig funktion med en annan signatur.
Beskriva en SQL-funktion
> DESCRIBE FUNCTION hello;
Function: hello
Type: SCALAR
Input: ()
Returns: STRING
> DESCRIBE FUNCTION area;
Function: default.area
Type: SCALAR
Input: x DOUBLE
y DOUBLE
Returns: DOUBLE
> DESCRIBE FUNCTION roll_dice;
Function: default.roll_dice
Type: SCALAR
Input: num_dice INT
num_sides INT
Returns: INT
> DESCRIBE FUNCTION EXTENDED roll_dice;
Function: default.roll_dice
Type: SCALAR
Input: num_dice INT DEFAULT 1 'number of dice to roll (Default: 1)'
num_sides INT DEFAULT 6 'number of sides per dice (Default: 6)'
Returns: INT
Comment: Roll a number of m-sided dice
Deterministic: false
Data Access: CONTAINS SQL
Configs: ...
Owner: the.house@always.wins
Create Time: Sat Feb 12 09:29:02 PST 2022
Body: aggregate(sequence(1, roll_dice.num_dice, 1),
0,
(acc, x) -> (rand() * roll_dice.num_sides)::int,
acc -> acc + roll_dice.num_dice)
Skapa Python-funktioner
—- Hello World-like functionality using Python UDFs
> CREATE FUNCTION main.default.greet(s STRING)
RETURNS STRING
LANGUAGE PYTHON
AS $$
def greet(name):
return "Hello " + name + "!"
return greet(s) if s else None
$$
—- Can import functions from std library and environment
> CREATE FUNCTION main.default.isleapyear(year INT)
RETURNS BOOLEAN
LANGUAGE PYTHON
AS $$
import calendar
return calendar.isleap(year) if year else None
$$
—- Must return the correct type. Otherwise will fail at runtime.
> CREATE FUNCTION main.default.a_number()
RETURNS INTEGER
LANGUAGE PYTHON
AS $$
# does not work: return "10"
# does not work: return 3.14
return 10
$$
—- Deal with exceptions.
> CREATE FUNCTION main.default.custom_divide(n1 INT, n2 INT)
RETURNS FLOAT
LANGUAGE PYTHON
AS $$
try:
return n1/n2
except ZeroDivisionException:
# in case of 0, we can return NULL.
return None
$$