Aufrufen einer UDF¶
Sie können eine benutzerdefinierte Funktion (UDF) oder eine benutzerdefinierte Tabellenfunktion (UDTF) auf die gleiche Weise aufrufen wie andere Funktionen.
Aufrufen einer UDF¶
Im Allgemeinen rufen Sie eine UDF auf dieselbe Weise auf wie andere Funktionen.
Wenn eine UDF über Argumente verfügt, können Sie diese Argumente über den Namen oder über die Position angeben.
Die folgende UDF akzeptiert zum Beispiel drei Argumente:
CREATE OR REPLACE FUNCTION udf_concatenate_strings(
first_arg VARCHAR,
second_arg VARCHAR,
third_arg VARCHAR)
RETURNS VARCHAR
LANGUAGE SQL
AS
$$
SELECT first_arg || second_arg || third_arg
$$;
Wenn Sie die UDF aufrufen, können Sie die Argumente über den Namen angeben:
SELECT udf_concatenate_strings(
first_arg => 'one',
second_arg => 'two',
third_arg => 'three');
+--------------------------+
| UDF_CONCATENATE_STRINGS( |
| FIRST_ARG => 'ONE', |
| SECOND_ARG => 'TWO', |
| THIRD_ARG => 'THREE') |
|--------------------------|
| onetwothree |
+--------------------------+
Wenn Sie die Argumente über den Namen angeben, müssen Sie die Argumente nicht in einer bestimmten Reihenfolge angeben:
SELECT udf_concatenate_strings(
third_arg => 'three',
first_arg => 'one',
second_arg => 'two');
+--------------------------+
| UDF_CONCATENATE_STRINGS( |
| THIRD_ARG => 'THREE', |
| FIRST_ARG => 'ONE', |
| SECOND_ARG => 'TWO') |
|--------------------------|
| onetwothree |
+--------------------------+
Sie können die Argumente auch über die Position angeben:
SELECT udf_concatenate_strings(
'one',
'two',
'three');
+--------------------------+
| UDF_CONCATENATE_STRINGS( |
| 'ONE', |
| 'TWO', |
| 'THREE') |
|--------------------------|
| onetwothree |
+--------------------------+
Beachten Sie Folgendes:
Sie müssen alle Argumente entweder über den Namen oder über die Position angeben. Sie können nicht einige der Argumente über den Namen und andere Argumente über die Position angeben.
Wenn Sie ein Argument über den Namen angeben, können Sie den Argumentnamen nicht in doppelten Anführungszeichen einschließen.
Wenn zwei Funktionen oder zwei Prozeduren den gleichen Namen, aber unterschiedliche Argumenttypen haben, können Sie die Argumentnamen verwenden, um anzugeben, welche Funktion bzw. Prozedur ausgeführt werden soll, allerdings müssen die Argumentnamen unterschiedlich sein. Weitere Informationen dazu finden Sie unter Überladen von Prozeduren und Funktionen.
Aufrufen einer UDF mit optionalen Argumenten¶
Wenn die UDF optionale Argumente hat, können Sie die optionalen Argumente beim Aufrufen weglassen. Jedes optionale Argument hat einen Standardwert, der verwendet wird, wenn das Argument weggelassen wird.
Die folgende UDF hat zum Beispiel ein erforderliches Argument und zwei optionale Argumente. Jedes optionale Argument hat einen Standardwert.
CREATE OR REPLACE FUNCTION build_string_udf(
word VARCHAR,
prefix VARCHAR DEFAULT 'pre-',
suffix VARCHAR DEFAULT '-post'
)
RETURNS VARCHAR
AS
$$
SELECT prefix || word || suffix
$$
;
Sie können jedes der optionalen Argumente in dem Aufruf weglassen. Wenn Sie ein Argument weglassen, wird der Standardwert dieses Arguments verwendet.
SELECT build_string_udf('hello');
+---------------------------+
| BUILD_STRING_UDF('HELLO') |
|---------------------------|
| pre-hello-post |
+---------------------------+
SELECT build_string_udf('hello', 'before-');
+--------------------------------------+
| BUILD_STRING_UDF('HELLO', 'BEFORE-') |
|--------------------------------------|
| before-hello-post |
+--------------------------------------+
Wenn Sie ein optionales Argument weglassen und ein anderes optionales Argument angeben müssen, das in der Signatur nach dem weggelassenen Argument positioniert ist, müssen Sie benannte Argumente und keine Positionsargumente verwenden.
Angenommen, Sie lassen das Argument prefix
weg und müssen aber das Argument suffix
angeben. Das Argument suffix
ist in der Signatur nach dem Argument prefix
positioniert, sodass Sie die Argumente mit Namen angeben müssen:
SELECT build_string_udf(word => 'hello', suffix => '-after');
+-------------------------------------------------------+
| BUILD_STRING_UDF(WORD => 'HELLO', SUFFIX => '-AFTER') |
|-------------------------------------------------------|
| pre-hello-after |
+-------------------------------------------------------+
Aufrufen einer UDTF¶
Sie können eine UDTF so aufrufen wie jede andere Tabellenfunktion auch. Wenn Sie eine UDTF in der FROM-Klausel einer Abfrage aufrufen, geben Sie den Namen und die Argumente der UDTF innerhalb der Klammern an, die dem Schlüsselwort TABLE folgen. Dies entspricht dem Vorgehen beim Aufrufen einer integrierten Tabellenfunktion.
Verwenden Sie beim Aufrufen einer UDTF das Schlüsselwort TABLE in etwa wie folgt:
SELECT ...
FROM TABLE ( udtf_name (udtf_arguments) )
Der Code im folgenden Beispiel ruft die Tabellenfunktion my_java_udtf
auf und gibt ein DATE-Literal im Argument '2021-01-16'::DATE
an.
SELECT ...
FROM TABLE(my_java_udtf('2021-01-16'::DATE));
Das Argument einer Tabellenfunktion kann auch ein Ausdruck sein, nicht nur ein Literal. Eine Tabellenfunktion kann zum Beispiel unter Verwendung einer Spalte aus einer Tabelle aufgerufen werden. Einige Beispiele finden Sie unten, einschließlich im Abschnitt Beispiele.
Wie beim Aufrufen von UDFs können Sie die Argumente über den Namen oder über die Position angeben.
Weitere allgemeine Informationen zu Tabellenfunktionen finden Sie unter Tabellenfunktion.
Bemerkung
Eine UDF kann nicht innerhalb der DEFAULT-Klausel einer CREATE TABLE-Anweisung aufgerufen werden.
Verwenden einer Tabelle oder UDTF als Eingabe für eine UDTF¶
Die Eingabe für eine Tabellenfunktion kann aus einer Tabelle oder aus einer anderen UDTF stammen, wie unter Verwenden einer Tabelle als Eingabe einer Tabellenfunktion dokumentiert.
Das folgende Beispiel zeigt, wie eine Tabelle als Eingabe der UDTF split_file_into_words
verwendet werden kann:
create table file_names (file_name varchar);
insert into file_names (file_name) values ('sample.txt'),
('sample_2.txt');
select f.file_name, w.word
from file_names as f, table(split_file_into_words(f.file_name)) as w;
Die Ausgabe sollte ungefähr wir folgt aussehen:
+-------------------+------------+
| FILE_NAME | WORD |
+-------------------+------------+
| sample_data.txt | some |
| sample_data.txt | words |
| sample_data_2.txt | additional |
| sample_data_2.txt | words |
+-------------------+------------+
Die IMPORTS-Klausel der UDTF muss den Namen und den Pfad von jeder Datei angeben, die an die UDTF übergeben wird. Beispiel:
create function split_file_into_words(inputFileName string)
...
imports = ('@inline_jars/sample.txt', '@inline_jars/sample_2.txt')
...
Jede Datei muss bereits in einen Stagingbereich (in diesem Fall in den Stagingbereich mit dem Namen @inline_jars
) kopiert worden sein, bevor die UDTF die Datei liest.
Ein Beispiel für die Verwendung einer UDTF als Eingabe einer anderen UDTF finden Sie in der JavaScript-UDTF-Dokumentation unter Erweiterte Beispiele mit Tabellenwerten und anderen UDTFs als Eingabe.
Tabellenfunktionen und Partitionen¶
Bevor Zeilen an Tabellenfunktionen übergeben werden, können die Zeilen in Partitionen gruppiert werden. Die Partitionierung hat zwei wesentliche Vorteile:
Die Partitionierung ermöglicht Snowflake eine Aufteilung des Workloads, wodurch sich die Parallelisierung und damit die Leistung verbessern lässt.
Die Partitionierung ermöglicht es Snowflake, alle Zeilen mit einem gemeinsamen Merkmal als Gruppe zu verarbeiten. Sie können Ergebnisse zurückgeben, die auf allen Zeilen einer Gruppe basieren, nicht nur auf einzelnen Zeilen.
Sie können beispielsweise Daten zu Aktienkursen in eine Gruppe pro Aktie partitionieren. Alle Aktienkurse eines Unternehmens können zusammen analysiert werden, während die Aktienkurse jedes Unternehmens unabhängig von jedem anderen Unternehmen analysiert werden können.
Daten können explizit oder implizit partitioniert werden.
Explizite Partitionierung¶
Explizite Partitionierung in mehrere Gruppen
Mit der folgenden Anweisung wird die UDTF namens my_udtf
auf einzelnen Partitionen aufgerufen. Jede Partition enthält alle Zeilen, für die der PARTITION BY
-Ausdruck denselben Wert ergibt (z. B. dieselbe Firma oder dasselbe Aktiensymbol).
SELECT *
FROM stocks_table AS st,
TABLE(my_udtf(st.symbol, st.transaction_date, st.price) OVER (PARTITION BY st.symbol))
Explizite Partitionierung in eine einzige Gruppe
Mit der folgenden Anweisung wird die UDTF namens my_udtf
auf einer Partition aufgerufen. Die Klausel PARTITION BY <Konstante>
(in diesem Fall PARTITION BY 1
) bringt alle Zeilen in dieselbe Partition.
SELECT *
FROM stocks_table AS st,
TABLE(my_udtf(st.symbol, st.transaction_date, st.price) OVER (PARTITION BY 1))
Ein vollständigeres und realistischeres Beispiel finden Sie unter Beispiele für den Aufruf von Java-UDTFs in Abfragen, insbesondere im Unterabschnitt Einzelne Partition.
Sortieren von Zeilen für Partitionen
Wenn die Zeilen einer Partition in einer bestimmten Reihenfolge verarbeiten werden sollen, fügen Sie eine ORDER BY-Klausel hinzu. Diese weist Snowflake an, die Zeilen in der angegebenen Reihenfolge an die Handler-Zeilenmethode zu übergeben.
Wenn Sie z. B. den gleitenden Durchschnitt eines Aktienkurses über die Zeit berechnen möchten, dann sortieren Sie die Aktienkurse nach Zeitstempel (und führen eine Partitionierung nach Aktiensymbol aus). Im folgenden Beispiel wird gezeigt, wie Sie dies tun können:
SELECT *
FROM stocks_table AS st,
TABLE(my_udtf(st.symbol, st.transaction_date, st.price) OVER (PARTITION BY st.symbol ORDER BY st.transaction_date))
Eine OVER-Klausel kann eine ORDER BY-Klausel auch ohne PARTITION BY-Klausel enthalten.
Denken Sie daran, dass das Einfügen einer ORDER BY-Klausel in eine OVER-Klausel nicht dasselbe ist wie das Einfügen einer ORDER BY-Klausel auf der äußersten Ebene der Abfrage. Wenn Sie möchten, dass die gesamten Abfrageergebnisse sortiert werden, benötigen Sie eine separate ORDER BY-Klausel. Beispiel:
SELECT *
FROM stocks_table AS st,
TABLE(my_udtf(st.symbol, st.transaction_date, st.price) OVER (PARTITION BY st.symbol ORDER BY st.transaction_date))
ORDER BY st.symbol, st.transaction_date, st.transaction_time;
Nutzungshinweise für die explizite Partitionierung
Wenn Sie eine UDTF mit einer PARTITION BY-Klausel verwenden, darf die PARTITION BY-Klausel nur einen Spaltenverweis oder ein Literal, aber keinen allgemeinen Ausdruck enthalten. Folgender Befehl wird beispielsweise nicht unterstützt:
SELECT * FROM udtf_table, TABLE(my_func(col1) OVER (PARTITION BY udtf_table.col2 * 2)); -- NO!
Implizite Partitionierung¶
Wenn eine Tabellenfunktion keine explizite Partitionierung der Zeilen mithilfe der PARTITION BY-Klausel vornimmt, partitioniert Snowflake die Zeilen in der Regel implizit, um mittels Parallelverarbeitung die Performance zu erhöhen.
Die Anzahl der Partitionen richtet sich in der Regel nach Faktoren wie der Größe des Warehouses, über das die Funktion ausgeführt wird, und der Kardinalität der Eingabebeziehung. Die Zeilen werden in der Regel auf Grundlage von Faktoren wie dem physischen Speicherort der Zeilen bestimmten Partitionen zugeordnet (z. B. durch Mikropartitionierung), sodass die Partitionsgruppierung nicht sinnvoll ist.