Entwerfen von Java-UDFs

Dieses Thema bietet Unterstützung beim Entwerfen von Java-UDFs.

Unter diesem Thema:

Auswählen Ihrer Datentypen

Bevor Sie Ihren Code schreiben:

  • Wählen Sie die Datentypen aus, die Ihre Funktion als Argumente akzeptieren soll, und den Datentyp, den Ihre Funktion zurückgeben soll.

  • Berücksichtigen Sie die Zeitzonenproblematik.

  • Entscheiden Sie, wie NULL-Werte behandelt werden sollen.

Zuordnung von SQL-Java-Datentypen für Parameter und Rückgabetypen

Die folgende Tabelle zeigt die Typzuordnungen zwischen SQL und Java. Diese Zuordnungen gelten im Allgemeinen sowohl für die Argumente, die an die Java-UDF übergeben werden, als auch für die Werte, die von der UDF zurückgegeben werden. Es gibt jedoch einige Ausnahmen, die in Fußnoten ausgeführt werden.

Einige SQL-Datentypen (z. B. NUMBER) sind mit mehreren Java-Datentypen kompatibel (z. B. int, long). In diesen Fällen können Sie einen beliebigen Java-Datentyp verwenden, der genügend Kapazität hat, um die tatsächlich zu übergebenden Werte aufzunehmen. Wenn Sie einen SQL-Wert an einen inkompatiblen Java-Datentyp übergeben (oder umgekehrt), gibt Snowflake einen Fehler aus.

SQL-Typ

Java-Typ

Anmerkungen

NUMBER

short

Darf nicht null sein. Muss in den Bereich von short passen (ohne Bruchteil, und ganzzahliger Teil darf die max/min-Werte von short nicht überschreiten).

NUMBER

Short

Muss in den Bereich von short passen (ohne Bruchteil, und ganzzahliger Teil darf die max/min-Werte von short nicht überschreiten).

NUMBER

int

Darf nicht null sein. Muss in den Bereich von int passen (ohne Bruchteil, und ganzzahliger Teil darf die max/min-Werte von int nicht überschreiten).

NUMBER

Integer

Muss in den Bereich von int passen (ohne Bruchteil, und ganzzahliger Teil darf die max/min-Werte von int nicht überschreiten).

NUMBER

long

Darf nicht null sein. Muss in den Bereich von long passen (ohne Bruchteil, und ganzzahliger Teil darf die max/min-Werte von long nicht überschreiten).

NUMBER

Long

Muss in den Bereich von long passen (ohne Bruchteil, und ganzzahliger Teil darf die max/min-Werte von long nicht überschreiten).

NUMBER

java.math.BigDecimal

NUMBER

java.math.BigInteger

Muss in den Bereich von BigInteger passen (ohne Bruchteil).

NUMBER

String

FLOAT

double

Darf nicht null sein.

FLOAT

Double

FLOAT

float

Darf nicht null sein. Kann zu Genauigkeitsverlust führen.

FLOAT

Float

Kann zu Genauigkeitsverlust führen.

FLOAT

String

Kann zu Genauigkeitsverlust führen (float -> string-Konvertierung ist verlustbehaftet).

VARCHAR

String

BINARY

byte[]

BINARY

String

Kodiert die binäre Zeichenfolge in hexadezimale Form. 4

BOOLEAN

boolean

Darf nicht null sein.

BOOLEAN

Boolean

BOOLEAN

String

4

DATE

java.sql.Date

DATE

String

Formatiert das Datum als YYYY-MM-DD. 4

TIME

java.sql.Time

3

TIME

String

Formatiert die Uhrzeit als HH:MI:SS.SSSSSSSSS, wobei der Sekundenbruchteil von der Genauigkeit der Uhrzeit abhängt. 3

TIMESTAMP_LTZ

java.sql.Timestamp

Muss in den Bereich von java.sql.Timestamp passen. 3

TIMESTAMP_LTZ

String

Das Ausgabeformat ist DY, DD MON YYYY HH24:MI:SS TZHTZM. 1, 3, 4

TIMESTAMP_NTZ

java.sql.Timestamp

Muss in den Bereich von java.sql.Timestamp passen. Behandelt die Gesamtbetrachtungszeit (Wall Clock Time) als Versatz von der Unix-Epoche (erzwingt effektiv eine UTC-Zeitzone). 3

TIMESTAMP_NTZ

String

Behandelt die Gesamtbetrachtungszeit (Wall Clock Time) als Versatz von der Unix-Epoche (erzwingt effektiv eine UTC-Zeitzone). Das Ausgabeformat ist DY, DD MON YYYY HH:MI:SS. 2, 3, 4

TIMESTAMP_TZ

java.sql.Timestamp

Muss in den Bereich von java.sql.Timestamp passen. 3

TIMESTAMP_TZ

String

Das Ausgabeformat ist DY, DD MON YYYY HH24:MI:SS TZHTZM. 1, 3, 4

VARIANT

String

Formatiert den Wert abhängig vom Typ, der dargestellt wird. Variante null wird als die Zeichenfolge „null“ formatiert.

OBJECT

Map<String, String>

Die Schlüssel der Zuordnung (Map) sind die Schlüssel des Objekts, und die Werte sind als Zeichenfolgen formatiert.

OBJECT

String

Formatiert das Objekt als JSON-Zeichenfolge (z. B. {"x": 3, "y": true}).

ARRAY

String[]

Formatiert die Elemente des Arrays als Zeichenfolgen.

ARRAY

String

Formatiert das Array als JSON-Zeichenfolge (z. B. [1, "foo", null]).

GEOGRAPHY

String

Formatiert das Geography-Element als GeoJSON.

1(1,2)

Das Format stimmt mit dem Internet (RFC)-Zeitstempelformat DY, DD MON YYYY HH24:MI:SS TZHTZM überein, wie unter Zeitstempelformate beschrieben. Wenn ein Zeitzonenversatz (die TZHTZM-Komponente) vorhanden ist, handelt es sich in der Regel um Ziffern (z. B. steht -0700 für 7 Stunden hinter UTC). Wenn der Zeitzonenversatz Z (für „Zulu“) anstelle von Ziffern angegeben wird, ist das gleichbedeutend mit „+0000“ (UTC).

2

Das Format stimmt mit dem Internet (RFC)-Zeitstempelformat DY, DD MON YYYY HH24:MI:SS überein, wie unter Zeitstempelformate beschrieben. Wenn auf die Zeichenfolge ein Leerzeichen und Z (für „Zulu“) folgt, wird der Versatz explizit mit „0000“ (UTC) angegeben.

3(1,2,3,4,5,6,7,8)

Obwohl Snowflake Zeitwerte mit Nanosekundengenauigkeit speichern kann, bietet die java.sql.time-Bibliothek nur Millisekundengenauigkeit. Die Konvertierung zwischen Snowflake- und Java-Datentypen kann die effektive Genauigkeit auf Millisekunden reduzieren.

4(1,2,3,4,5,6)

Diese Typzuordnung wird bei der Konvertierung von SQL-Argumenten nach Java unterstützt, aber nicht bei der Konvertierung von Java-Rückgabetypen in SQL-Typen.

TIMESTAMP_LTZ-Werte und Zeitzonen

Ein Java-UDF ist weitgehend isoliert von der Umgebung, in der sie aufgerufen wird. Die Zeitzone wird jedoch von der aufrufenden Umgebung geerbt. Wenn die Sitzung des Aufrufers vor dem Aufruf der Java-UDF eine Standardzeitzone eingestellt hat, dann hat die Java-UDF die gleiche Standardzeitzone.

NULL-Werte

Snowflake unterstützt zwei verschiedene NULL-Werte: SQL NULL und VARIANT JSON null. (Weitere Informationen zu Snowflake VARIANT NULL finden Sie unter NULL-Werte.)

Java unterstützt einen null-Wert, der nur für nicht primitive Datentypen gilt.

Ein SQL-NULL-Argument für eine Java-UDF wird in den Java null-Wert übersetzt, aber nur für Java-Datentypen, die null unterstützen.

Ein zurückgegebener Java null-Wert wird in SQL NULL zurückübersetzt.

Arrays und variable Anzahl von Argumenten

Java-UDFs können Arrays von jedem der folgenden Java-Datentypen erhalten:

  • String

  • boolean

  • double

  • float

  • int

  • long

  • short

Der Datentyp von übergebenen SQL-Werten muss mit dem entsprechenden Java-Datentyp kompatibel sein. Weitere Informationen zur Datentypkompatibilität finden Sie unter Zuordnung von SQL-Java-Datentypen für Parameter und Rückgabetypen.

Die folgenden zusätzlichen Regeln gelten für jeden der angegebenen Java-Datentypen:

  • boolean: Das Snowflake-ARRAY darf nur BOOLEAN-Elemente und keine NULL-Werte enthalten.

  • int/short/long: Das Snowflake-ARRAY darf nur Festkomma-Elemente mit einer Skalierung von 0 enthalten und auch keine NULL-Werte.

  • float/double: Das Snowflake-ARRAY muss enthalten:

    Das ARRAY darf keine NULL-Werte enthalten.

Java-Methoden können diese Arrays auf eine von zwei Arten erhalten:

  • Verwendung der Array-Funktion von Java.

  • Verwendung der Java-Funktion varargs (variable Anzahl von Argumenten).

In beiden Fällen muss Ihr SQL-Code ein ARRAY übergeben.

Werteübergabe via ARRAY

Deklarieren Sie den Java-Parameter als Array. In der folgenden Methode ist dritte Parameter beispielsweise ein String-Array:

static int MyMethod(int fixed_argument_1, int fixed_argument_2, String[] string_array)

Nachfolgend finden Sie ein vollständiges Beispiel:

Erstellen und Laden der Tabelle:

CREATE TABLE string_array_table(id INTEGER, a ARRAY);
INSERT INTO string_array_table (id, a) SELECT
        1, ARRAY_CONSTRUCT('Hello');
INSERT INTO string_array_table (id, a) SELECT
        2, ARRAY_CONSTRUCT('Hello', 'Jay');
INSERT INTO string_array_table (id, a) SELECT
        3, ARRAY_CONSTRUCT('Hello', 'Jay', 'Smith');

Erstellen der UDF:

create or replace function concat_varchar_2(a ARRAY)
returns varchar
language java
handler='TestFunc_2.concat_varchar_2'
target_path='@~/TestFunc_2.jar'
as
$$
    class TestFunc_2 {
        public static String concat_varchar_2(String[] string_array) {
            return String.join(" ", string_array);
        }
    }
$$;

Aufrufen der UDF:

SELECT concat_varchar_2(a)
    FROM string_array_table
    ORDER BY id;
+---------------------+
| CONCAT_VARCHAR_2(A) |
|---------------------|
| Hello               |
| Hello Jay           |
| Hello Jay Smith     |
+---------------------+

Werteübergabe via varargs

Die Verwendung von varargs ist der Verwendung eines Arrays sehr ähnlich.

Verwenden Sie in Ihrem Java-Code den varargs-Deklarationsstil von Java:

static int MyMethod(int fixed_argument_1, int fixed_argument_2, String ... string_array)

Nachfolgend finden Sie ein vollständiges Beispiel. Der einzige wesentliche Unterschied zwischen diesem Beispiel und dem vorangegangenen Beispiel (für Arrays) ist die Deklaration der Parameter für die Methode.

Erstellen und Laden der Tabelle:

CREATE TABLE string_array_table(id INTEGER, a ARRAY);
INSERT INTO string_array_table (id, a) SELECT
        1, ARRAY_CONSTRUCT('Hello');
INSERT INTO string_array_table (id, a) SELECT
        2, ARRAY_CONSTRUCT('Hello', 'Jay');
INSERT INTO string_array_table (id, a) SELECT
        3, ARRAY_CONSTRUCT('Hello', 'Jay', 'Smith');

Erstellen der UDF:

create or replace function concat_varchar(a ARRAY)
returns varchar
language java
handler='TestFunc.concat_varchar'
target_path='@~/TestFunc.jar'
as
$$
    class TestFunc {
        public static String concat_varchar(String ... string_array) {
            return String.join(" ", string_array);
        }
    }
$$;

Aufrufen der UDF:

SELECT concat_varchar(a)
    FROM string_array_table
    ORDER BY id;
+-------------------+
| CONCAT_VARCHAR(A) |
|-------------------|
| Hello             |
| Hello Jay         |
| Hello Jay Smith   |
+-------------------+

Entwerfen von Java-UDFs unter Berücksichtigung der Snowflake-bedingten Einschränkungen

Um die Stabilität in der Snowflake-Umgebung sicherzustellen, hat Snowflake die folgenden Einschränkungen für Java-UDFs definiert. Wenn nicht anders angegeben, werden diese Einschränkungen bei der Ausführung der Java-UDF erzwungen, nicht bei der Erstellung.

Speicher

Vermeiden Sie einen zu hohen Verbrauch von Speicher.

  • Große Datenwerte (typischerweise BINARY-, lange VARCHAR- oder große OBJECT- oder VARIANT-Datentypen) benötigen viel Speicher.

  • Eine zu große Stapeltiefe kann eine große Menge an Speicher verbrauchen. Snowflake hat einfache Funktionsaufrufe mit einer Verschachtelungstiefe von 50 Ebenen ohne Fehler getestet. Die praktische Maximalgrenze hängt davon ab, wie viele Informationen im Stapel abgelegt werden.

UDFs geben einen Fehler zurück, wenn sie zu viel Speicher verbrauchen. Das jeweilige Limit kann sich ändern.

Zeit

Vermeiden Sie Algorithmen, die pro Aufruf sehr viel Zeit benötigen.

Wenn eine UDF-Anweisung zu lange dauert, bricht Snowflake die SQL-Anweisung ab und gibt einen Fehler an den Benutzer zurück. Dieses Limit begrenzt die Auswirkungen (und Kosten) von Fehlern wie Endlosschleifen.

Bibliotheken

Obwohl Ihre Java-Methode Klassen und Methoden aus Standard-Java-Bibliotheken verwenden kann, deaktivieren die Sicherheitsrestriktionen von Snowflake einige Funktionen, wie z. B. das Schreiben in Dateien. Einzelheiten zu Bibliothekseinschränkungen finden Sie im Abschnitt Einsetzen von bewährten Sicherheitsmethoden.

Entwerfen der Klasse

Wenn eine SQL-Anweisung Ihre Java-UDF aufruft, ruft Snowflake eine Java-Methode auf, die Sie geschrieben haben. Ihre Java-Methode wird als „Handler-Methode“ oder kurz „Handler“ bezeichnet.

Wie bei jeder Java-Methode muss Ihre Methode als Teil einer Klasse deklariert werden. Ihre Handler-Methode kann eine statische Methode oder eine Instanzenmethode der Klasse sein. Wenn Ihr Handler eine Instanzenmethode ist und Ihre Klasse einen Konstruktor ohne Argumente definiert, ruft Snowflake den Konstruktor zur Initialisierungszeit auf, um eine Instanz Ihrer Klasse zu erstellen. Wenn Ihr Handler eine statische Methode ist, muss Ihre Klasse keinen Konstruktor haben.

Der Handler wird für jede an die Java-UDF übergebene Zeile einmal aufgerufen. (Hinweis: Es wird nicht für jede Zeile eine neue Instanz der Klasse erstellt. Snowflake kann die Handler-Methode derselben Instanz mehrmals aufrufen oder dieselbe statische Methode mehrmals aufrufen).

Um die Ausführung Ihres Codes zu optimieren, geht Snowflake davon aus, dass die Initialisierung langsam sein kann, während die Ausführung der Handler-Methode schnell ist. Snowflake verwendet ein längeres Timeout für die Ausführung der Initialisierung (einschließlich Zeit für Laden der UDF und Aufruf des Konstruktors der Klasse, die die Handler-Methode enthält, falls ein Konstruktor definiert ist) als für die Ausführung des Handlers (Zeit für Aufruf Ihres Handlers mit einer Zeile der Eingabe).

Weitere Informationen zum Entwerfen der Klasse finden Sie unter Erstellen von Java-UDFs.

Optimieren von Initialisierung und Steuerung des globalen Zustands in skalaren UDFs

Die meisten skalaren UDFs müssen den folgenden Richtlinien folgen:

  • Wenn Sie einen gemeinsamen Zustand (Shared State) initialisieren müssen, der sich über Zeilen hinweg nicht ändert, initialisieren Sie ihn im Konstruktor der UDF-Klasse.

  • Schreiben Sie Ihre Handler-Methode so, dass sie Thread-sicher ist.

  • Vermeiden Sie das Speichern und Freigeben eines dynamischen Zustands über Zeilen hinweg.

Wenn Ihre UDF diesen Richtlinien nicht folgen kann oder wenn Sie ein tieferes Verständnis der Gründe für diese Richtlinien wünschen, lesen Sie die nächsten Unterabschnitte.

Einführung

Snowflake erwartet, dass skalare UDFs unabhängig verarbeitet werden. Wenn Sie sich zwischen Aufrufen auf einen gemeinsamen Zustand verlassen, kann dies zu unerwartetem Verhalten führen, da das System Zeilen in beliebiger Reihenfolge verarbeiten und diese Aufrufe auf mehrere JVMs verteilen kann. Bei UDFs sollte es vermieden werden, dass sich beim Aufrufen der Handler-Methode auf einen gemeinsamen Zustand verlassen wird. Es gibt jedoch zwei Situationen, in denen Sie möglicherweise möchten, dass eine UDF einen gemeinsamen Zustand speichert:

  • Code, der teure Initialisierungslogik enthält, die nicht bei jeder Zeile wiederholt werden soll.

  • Code, der einen gemeinsamen Zustand über Zeilen hinweg nutzt, z. B. als Cache.

Wenn Sie den Zustand über mehrere Zeilen hinweg gemeinsam nutzen müssen und sich dieser Zustand im Laufe der Zeit nicht ändert, dann verwenden Sie einen Konstruktor, um den gemeinsamen Zustand durch das Einstellen von Variablen auf Instanzenebene zu erstellen. Der Konstruktor wird nur einmal pro Instanz ausgeführt, während der Handler einmal pro Zeile aufgerufen wird, sodass die Initialisierung im Konstruktor günstiger ist, wenn ein Handler mehrere Zeilen verarbeitet. Und da der Konstruktor nur einmal aufgerufen wird, muss er nicht thread-sicher geschrieben werden.

Wenn Ihre UDF einen gemeinsamen Zustand speichert, der sich ändert, muss Ihr Code darauf vorbereitet sein, den gleichzeitigen Zugriff mit diesem Zustand zu verarbeiten. In den nächsten beiden Abschnitten finden Sie weitere Informationen zur Parallelität und zum gemeinsamen Zustand.

Erläuterungen zur Java-UDF-Parallelisierung

Um die Verarbeitungsleistung zu verbessern, nutzt Snowflake die Parallelisierung sowohl zwischen mehrere JVMs als auch innerhalb von JVMs.

  • Mehrere JVMs:

    Snowflake parallelisiert mehrere Ausführungen in einem Warehouse. Jede Ausführung nutzt eine (oder mehrere) JVMs. Dies bedeutet, dass es keinen globalen gemeinsamen Zustand gibt. Der Zustand kann höchstens innerhalb einer einzelnen JVM gemeinsam genutzt werden.

  • Innerhalb von JVMs:

    • Jede JVM kann mehrere Threads ausführen, die parallel die Handler-Methode der gleichen Instanz aufrufen können. Das bedeutet, dass jede Handler-Methode thread-sicher sein muss.

    • Wenn eine SQL-Anweisung dieselbe UDF mehr als einmal mit denselben Argumenten für dieselbe Zeile aufruft, dann gibt die UDF bei jedem Aufruf für diese Zeile den gleichen Wert zurück. Im Folgenden wird z. B. zweimal derselbe Wert für jede Zeile zurückgegeben:

      select
             my_java_udf(42),
             my_java_udf(42)
          from table1;
      

      Wenn Sie möchten, dass mehrere Aufrufe unabhängige Werte zurückgeben, auch wenn die gleichen Argumente übergeben werden, dann binden Sie mehrere separate UDFs an die gleiche Handler-Methode. Beispiel:

      1. Erstellen Sie eine JAR-Datei mit dem Namen @java_udf_stage/rand.jar mit Code:

        class MyClass {
        
            private double x;
        
            // Constructor
            public MyClass()  {
                x = Math.random();
            }
        
            // Handler
            public double myHandler() {
                return x;
            }
        }
        
      2. Erstellen Sie die Java-UDFs wie unten gezeigt. Diese UDFs haben unterschiedliche Namen, verwenden aber die gleiche JAR-Datei und innerhalb dieser JAR-Datei den gleichen Handler.

        create my_java_udf_1()
            returns double
            language java
            imports = ('@java_udf_stage/rand.jar')
            handler = 'MyClass.myHandler';
        
        create my_java_udf_2()
            returns double
            language java
            imports = ('@java_udf_stage/rand.jar')
            handler = 'MyClass.myHandler';
        
      3. Der folgende Code ruft beide UDFs auf. Die UDFs verweisen auf die gleiche JAR-Datei und den gleichen Handler. Diese Aufrufe erstellen zwei Instanzen der gleichen Klasse. Jede Instanz gibt einen unabhängigen Wert zurück, sodass das folgende Beispiel zwei unabhängige Werte zurückgibt, anstatt zweimal denselben Wert zu liefern:

        select
                my_java_udf_1(),
                my_java_udf_2()
            from table1;
        

Speichern von JVM-Statusinformationen

Ein Grund, sich nicht auf einen dynamischen gemeinsamen Zustand zu verlassen, besteht darin, dass Zeilen nicht unbedingt in einer vorhersehbaren Reihenfolge verarbeitet werden. Bei jeder Ausführung einer SQL-Anweisung kann Snowflake die Anzahl der Batches, die Reihenfolge, in der die Batches verarbeitet werden, und die Reihenfolge der Zeilen innerhalb eines Batches variieren. Wenn eine skalare UDF so gestaltet ist, dass eine Zeile den Rückgabewert einer nachfolgenden Zeile beeinflusst, dann kann die UDF bei jeder Ausführung unterschiedliche Ergebnisse zurückgeben.

Fehlerbehandlung

Eine als UDF verwendete Java-Methode kann die üblichen Java-Techniken zur Ausnahmebehandlung verwenden, um Fehler innerhalb der Methode abzufangen.

Wenn eine Ausnahme innerhalb der Methode auftritt und nicht von der Methode abgefangen wird, gibt Snowflake einen Fehler aus, der die Stapelüberwachung für die Ausnahme enthält.

Sie können explizit einen Fehler auszulösen, ohne ihn abzufangen, um die Abfrage zu beenden und einen SQL-Fehler zu erzeugen. Beispiel:

if (x < 0)  {
    throw new IllegalArgumentException("x must be non-negative.");
    }

Beim Debugging können Sie in den Text der SQL-Fehlermeldung Werte integrieren. Setzen Sie dazu den gesamten Textkörper der Java-Methode in einen „try-catch“-Block, und fügen Sie Argumentwerte zur abgefangenen Fehlermeldung hinzu. Lösen Sie dann einen Fehler mit der erweiterten Meldung aus. Um die Offenlegung sensibler Daten zu verhindern, entfernen Sie die Argumente, bevor Sie die JAR-Dateien in einer Produktionsumgebung bereitstellen.

Befolgen von Best Practices

  • Schreiben Sie plattformunabhängigen Code.

    • Vermeiden Sie Code, der eine bestimmte CPU-Architektur voraussetzt (z. B. x86).

    • Vermeiden Sie Code, der ein bestimmtes Betriebssystem voraussetzt.

  • Wenn Sie Initialisierungscode ausführen müssen und diesen nicht in die aufgerufene Methode aufnehmen möchten, können Sie den Initialisierungscode in einen statischen Initialisierungsblock einfügen.

Siehe auch:

Einsetzen von bewährten Sicherheitsmethoden

  • Ihre Methode (und alle Bibliotheksmethoden, die Sie aufrufen) muss sich wie eine reine Funktion verhalten, die nur auf die empfangenen Daten einwirkt und einen auf diesen Daten basierenden Wert zurückgibt, ohne Nebeneffekte zu verursachen. Ihr Code sollte nicht versuchen, den Zustand des zugrunde liegenden Systems zu beeinflussen, abgesehen davon, dass er eine angemessene Menge an Speicher und Prozessorzeit verbraucht.

  • Java-UDFs werden innerhalb einer eingeschränkten Engine ausgeführt. Weder Ihr Code noch der Code in den Bibliotheksmethoden, die Sie verwenden, darf irgendwelche verbotenen Systemaufrufe bereitstellen, einschließlich:

    • Prozesssteuerung Sie können z. B. einen Prozess nicht aufspalten. (Sie können jedoch mehrere Threads verwenden.)

    • Zugriff auf das Dateisystem.

      Bis auf die folgenden Ausnahmen dürfen Java-UDFs keine Dateien lesen oder schreiben:

      • Java.UDFs können Dateien lesen, die in der imports-Klausel des CREATE FUNCTION-Befehls angegeben sind. Weitere Informationen dazu finden Sie unter CREATE FUNCTION.

      • Java-UDFs können Dateien, wie z. B. Protokolldateien, in das /tmp-Verzeichnis schreiben.

        Jede Abfrage erhält ein eigenes, mit Speicher unterstütztes Dateisystem mit eigenem „/tmp“-Verzeichnis, sodass bei verschiedenen Abfragen keine Dateinamenkonflikte auftreten können.

        Konflikte innerhalb einer Abfrage sind jedoch möglich, wenn eine einzelne Abfrage mehr als eine UDF aufruft und diese UDFs versuchen, in Dateien mit demselben Namen zu schreiben.

    • Netzwerkzugriff.

      Bemerkung

      Da Ihr Code weder direkt noch indirekt auf das Netzwerk zugreifen kann, können Sie für den Zugriff auf die Datenbank nicht den Code im Snowflake-JDBC-Treiber verwenden. Ihre UDF kann selbst nicht als Client von Snowflake agieren.

  • JNI (Java Native Interface) wird nicht unterstützt. Snowflake verbietet das Laden von Bibliotheken, die nativen Code (im Gegensatz zu Java-Bytecode) enthalten.