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 VARCHAR,
    second VARCHAR,
    third VARCHAR)
  RETURNS VARCHAR
  LANGUAGE SQL
  AS
  $$
    RETURN first || second || third;
  $$;
Copy

Wenn Sie die UDF aufrufen, können Sie die Argumente über den Namen angeben:

SELECT udf_concatenate_strings(
  first => 'one',
  second => 'two',
  third => 'three');
Copy

Wenn Sie die Argumente über den Namen angeben, müssen Sie die Argumente nicht in einer bestimmten Reihenfolge angeben:

SELECT udf_concatenate_strings(
  third => 'three',
  first => 'one',
  second => 'two');
Copy

Sie können die Argumente auch über die Position angeben:

SELECT udf_concatenate_strings(
  'one',
  'two',
  'three');
Copy

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
  $$
  ;
Copy

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');
Copy
+---------------------------+
| BUILD_STRING_UDF('HELLO') |
|---------------------------|
| pre-hello-post            |
+---------------------------+
SELECT build_string_udf('hello', 'before-');
Copy
+--------------------------------------+
| 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');
Copy
+-------------------------------------------------------+
| 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) )
Copy

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));
Copy

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;
Copy

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      |
+-------------------+------------+
Copy

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')
    ...
Copy

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))
Copy

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))
Copy

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))
Copy

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;
Copy

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!
Copy

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.