Speichern von Handler-Code inline oder in einem Stagingbereich

Wenn Sie eine benutzerdefinierte Funktion (UDF) oder eine gespeicherte Prozedur mit SQL erstellen, können Sie angeben, ob der Handler-Code inline mit der SQL-Anweisung, die den Code erstellt, verwendet werden soll oder außerhalb der SQL-Anweisung, z. B. in einer Datei in einem Stagingbereich. Unter diesem Thema wird der Unterschied genauer erläutert.

Unter diesem Thema:

Praktische Unterschiede

Vorteile von Inline-Handlern

Inline-Handler sind in der Regel einfacher zu implementieren. Nachdem Sie mit Ihren Entwicklungstools überprüft haben, ob Ihr Code ordnungsgemäß funktioniert, können Sie ihn bereitstellen, indem Sie ihn in die SQL-Anweisung kopieren und dann die Anweisung ausführen. Sie können den Code dort pflegen, indem Sie ihn mit einer SQL-Anweisung aktualisieren (z. B. mit ALTER FUNCTION oder ALTER PROCEDURE), ohne den Code an anderer Stelle pflegen zu müssen.

Vorteile von Handlern in einem Stagingbereich

Bei Verwendung eines Stagingbereichs-Handler gilt Folgendes:

  • Sie können bereits kompilierten Code verwenden, z. B. wenn Sie bereits eine kompilierte Ausgabe haben, aber nicht über den Quellcode verfügen.

  • Sie können Handler-Code verwenden, der zu groß ist, um ihn in die SQL-Anweisung einzufügen, mit der Sie die Funktion oder Prozedur erstellen. Für Inline-Code gibt es eine Obergrenze für die Quellcodegröße.

  • Sie können Handler-Code aus verschiedenen Funktionen oder Prozeduren wiederverwenden. Code im Stagingbereich kann mehrere Handler-Funktionen umfassen, wobei jede Funktion von einer anderen UDF oder Prozedur verwendet werden kann. Wenn Sie mehrere UDFs oder Prozeduren erstellen, können diese jeweils dieselbe Handler-Datei angeben, aber darin eine andere implementierte Handler-Funktion.

    Im Gegensatz dazu enthalten die Handler für Inline-Funktionen oder -Prozeduren normalerweise nur eine aufrufbare Funktion. Diese aufrufbare Funktion kann andere Funktionen aufrufen, und diese anderen Funktionen können in derselben Codedatei oder in einer anderen Codedatei in einem Stagingbereich definiert sein.

  • Es könnte effizienter sein, den meisten Teil der Entwicklungsarbeit mit vorhandenen Test- und Debugging-Tools zu erledigen. Dies gilt insbesondere, wenn der Code groß oder komplex ist.

Verwendung eines Inline-Handlers

Wenn Sie einen Inline-Handler verwenden, fügen Sie den Quellcode des Handlers in die AS-Klausel der SQL-Anweisung ein, mit der die Funktion oder Prozedur erstellt wird. Sie würden zum Beispiel den Handler-Code in die AS-Klausel der CREATE FUNCTION- oder CREATE PROCEDURE-Anweisung selbst aufnehmen.

Innerhalb der AS-Klausel schließen den Code in einfache Anführungszeichen oder einem Paar von Dollarzeichen ($$) ein. Möglicherweise ist die Verwendung von doppelten Dollarzeichen einfacher, z. B. wenn der Quellcode eingebettete einfache Anführungszeichen enthält.

Wenn der Quellcode des Inline-Handlers kompiliert werden muss (z. B. bei einem in Java oder Scala geschriebenen Handler), kompiliert Snowflake den Quellcode und speichert die Ausgabe (z. B. eine JAR-Datei) zur späteren Verwendung. Optional können Sie mit der TARGET_PATH-Klausel einen Speicherort für eine resultierende Ausgabedatei angeben.

Snowflake verwaltet kompilierte Ausgaben auf folgende Weise:

  • Wenn die SQL-Anweisung (z. B. CREATE FUNCTION) TARGET_PATH verwendet, um einen Speicherort für die Ausgabedatei anzugeben, kompiliert Snowflake den Code einmal und speichert die kompilierte Ausgabe zur späteren Verwendung.

  • Wenn die SQL-Anweisung keinen Speicherort für die Datei angibt, kompiliert Snowflake den Code für jede SQL-Anweisung neu, die die Funktion oder Prozedur aufruft. Snowflake löscht die Datei automatisch nach Beendigung der SQL-Anweisung.

Bemerkung

Als Best Practice bei der Verwendung eines Inline-Java- oder Inline-Scala-Handlers sollten Sie einen Wert für den Parameter TARGET_PATH angeben. Dies kann die Performance erhöhen, da Snowflake das kompilierte Ergebnis des Handler-Codes wiederverwendet, anstatt den Code für jeden Aufruf der Prozedur oder UDF neu zu kompilieren.

Achtung

Wenn Handler-Code inline definiert wird, wird er als Metadaten erfasst. Wenn Sie nicht möchten, dass der Code als Metadaten erfasst wird, können Sie ihn stattdessen auf andere Weise bereitstellen, z. B. durch Verwendung eines Stagingbereichs-Handlers.

Kunden müssen sicherstellen, dass bei der Nutzung des Snowflake-Dienstes keine personenbezogenen Daten (außer für ein Objekt „Benutzer“), sensible Daten, exportkontrollierte Daten oder andere regulierte Daten als Metadaten eingegeben werden. Weitere Informationen dazu finden Sie unter Metadatenfelder in Snowflake.

Inline-Beispiel mit Java-Handler

Der Code im folgenden Beispiel erstellt eine gespeicherte Prozedur MYPROC mit einem Inline-Handler in Java. Der Handler ist die Methode run der Klasse MyJavaClass.

CREATE OR REPLACE PROCEDURE MYPROC(fromTable STRING, toTable STRING, count INT)
  RETURNS STRING
  LANGUAGE JAVA
  RUNTIME_VERSION = '11'
  PACKAGES = ('com.snowflake:snowpark:latest')
  HANDLER = 'MyJavaClass.run'
  AS
  $$
    import com.snowflake.snowpark_java.*;

    public class MyJavaClass {
      public String run(Session session, String fromTable, String toTable, int count) {
        session.table(fromTable).limit(count).write().saveAsTable(toTable);
        return "SUCCESS";
      }
    }
  $$;
Copy

Referenzinformationen zu CREATE PROCEDURE finden Sie unter CREATE PROCEDURE.

Verwenden eines Staging-Handlers

Wenn Sie einen Staging-Handler verwenden, können Sie mit der IMPORTS-Klausel einen Handler referenzieren, der an einem anderen Speicherort, wie z. B. einem Stagingbereich, gespeichert ist. Sie würden zum Beispiel den Pfad zum Handler mit der IMPORTS-Klausel einer SQL-Anweisung wie CREATE PROCEDURE oder CREATE FUNCTION angeben.

Bereitstellen eines Handlers im Stagingbereich zur Verwendung durch eine Funktion oder Prozedur

Im Folgenden wird beschrieben, wie Sie eine Handler-Datei zu der Umgebung hinzufügen, in der Ihre Funktion oder Prozedur ausgeführt wird.

  1. Falls erforderlich, z. B. bei einem in Java oder Scala geschriebenen Handler, kompilieren und packen Sie den Handler-Code zum Hochladen in einen Stagingbereich. Weitere Informationen zu Build-Tools finden Sie unter Packen des Handler-Codes.

    Für einen in Python geschriebenen Handler können Sie die Quelle des Handler-Moduls verwenden.

  2. Laden Sie die Handler-Datei in einen Stagingbereich hoch, wie unter Abhängigkeiten für Code zur Verfügung stellen beschrieben.

  3. Verwenden Sie beim Erstellen der Funktion oder Prozedur eine Referenz auf die Handler-Datei.

    Sie referenzieren die Handler-Datei in der IMPORTS-Klausel, wie unter Referenzieren der Abhängigkeit beschrieben.

    Der Code im folgenden Beispiel erstellt eine UDF namens my_udf, deren Handler MyClass.myFunction in Java geschrieben ist. Die IMPORTS-Klausel im Code gibt an, dass sich die Handler-Datei mit dem Namen my_handler.jar im Stagingbereich mystage im Unterverzeichnis handlers befindet. Zur Laufzeit fügt Snowflake die Handler-JAR-Datei zum Klassenpfad hinzu.

    CREATE FUNCTION my_udf(i NUMBER)
      RETURNS NUMBER
      LANGUAGE JAVA
      IMPORTS = ('@mystage/handlers/my_handler.jar')
      HANDLER = 'MyClass.myFunction'
    
    Copy

    Referenzinformationen zu CREATE FUNCTION finden Sie unter CREATE FUNCTION.

Beschränkungen und Best Practices

Wenn Sie die Handler-Datei löschen oder umbenennen, kann die Funktion oder Prozedur nicht mehr aufgerufen werden. Wenn Sie die Handler-Datei aktualisieren müssen, gehen Sie wie folgt vor:

  • Stellen Sie zunächst sicher, dass keine Aufrufe der Funktion oder Prozedur erfolgen, die den Handler verwendet.

  • Verwenden Sie den Befehl PUT, um eine neue Handler-Datei hochzuladen. Wenn sich beim Hochladen der neuen Handler-Datei die alte Handler-Datei noch im Stagingbereich befindet, verwenden Sie die OVERWRITE=TRUE-Klausel des Befehls PUT, um die alte Handler-Datei zu überschreiben.