Kategorien:

Tabellenfunktionen

RESULT_SCAN

Gibt das Resultset eines vorherigen Befehls (innerhalb von 24 Stunden nach Ausführung der Abfrage) zurück, als wäre das Ergebnis eine Tabelle. Dies ist besonders nützlich, wenn Sie die Ausgabe aus einer der folgenden Situationen verarbeiten möchten:

Der Befehl/die Abfrage kann aus der aktuellen Sitzung oder einer Ihrer anderen Sitzungen, einschließlich vergangener Sitzungen, stammen, solange der Zeitraum von 24 Stunden nicht überschritten wird. Dieser Zeitraum ist nicht veränderbar. Weitere Details dazu finden Sie unter Verwenden von persistent gespeicherten Abfrageergebnissen.

Siehe auch:

DESCRIBE RESULT (Konto- und Sitzungs-DDL)

Syntax

RESULT_SCAN ( { '<query_id>'  | LAST_QUERY_ID() } )
Copy

Argumente

query_id oder LAST_QUERY_ID()

Entweder die ID für eine Abfrage, die Sie ausgeführt haben (innerhalb der letzten 24 Stunden in einer beliebigen Sitzung), oder die Funktion LAST_QUERY_ID, die die ID für eine Abfrage in Ihrer aktuellen Sitzung zurückgibt.

Nutzungshinweise

  • Wenn die ursprüngliche Abfrage manuell ausgeführt wird, kann nur der Benutzer, der die ursprüngliche Abfrage ausführt, die Funktion RESULT_SCAN verwenden, um die Ausgabe der Abfrage zu verarbeiten. Auch ein Benutzer mit der Berechtigung ACCOUNTADMIN kann nicht mit RESULT_SCAN auf die Ergebnisse der Abfrage eines anderen Benutzers zugreifen.

  • Wenn die ursprüngliche Abfrage über eine Aufgabe ausgeführt wird, erfolgt das Auslösen und Ausführen der Abfrage nicht durch einen bestimmten Benutzer sondern durch die Rolle, die Eigentümer der Aufgabe ist. Wenn ein Benutzer oder eine Aufgabe ebenfalls mit dieser Rolle agieren, können sie mit RESULT_SCAN auf die Abfrageergebnisse zugreifen.

  • Snowflake speichert alle Suchergebnisse für 24 Stunden. Diese Funktion gibt nur Ergebnisse für Abfragen zurück, die in diesem Zeitraum ausgeführt wurden.

  • Resultsets verfügen über keine verknüpften Metadaten, sodass die Verarbeitung großer Resultsets langsamer sein kann als die Abfrage einer tatsächlichen Tabelle.

  • Die Abfrage, die den RESULT_SCAN enthält, kann Klauseln wie Filter und ORDER BY enthalten, die sich nicht in der ursprünglichen Abfrage befanden. Auf diese Weise können Sie das Resultset eingrenzen oder ändern.

  • Es ist nicht garantiert, dass ein RESULT_SCAN Zeilen in der Reihenfolge zurückgibt, in der sie von der ursprünglichen Abfrage zurückgegeben wurden. Sie können eine ORDER BY-Klausel in den RESULT_SCAN einfügen, um eine bestimmte Reihenfolge festzulegen.

  • Verwenden Sie zum Abrufen der ID für eine bestimmte Abfrage eine der folgenden Methoden:

    Classic Console

    Klicken Sie an einer der folgenden Stellen auf den bereitgestellten Link, um die ID anzuzeigen/zu kopieren:

    • In Worksheets Worksheet tab enthalten die Ergebnisse nach dem Ausführen einer Abfrage einen Link für die ID.

    • In History History tab beinhaltet jede Abfrage die ID als Link.

    SQL

    Führen Sie eine der folgenden Funktionen aus:

  • Wenn RESULT_SCAN Abfrageausgaben verarbeitet, die doppelte Spaltennamen enthielten (z. B. eine Abfrage, bei der zwei Tabellen mit JOIN verknüpft wurden, die überlappende Spaltennamen aufweisen), verweist RESULT_SCAN auf die doppelten Spalten mit geänderten Namen und fügt „_1“, „_2“ usw. zum ursprünglichen Namen hinzu. Ein Beispiel dazu finden Sie unten im Abschnitt Beispiele.

Sortierungsdetails

Wenn RESULT_SCAN die Ergebnisse der vorherigen Anweisung zurückgibt, behält RESULT_SCAN die Sortierungsspezifikationen der zurückgegebenen Werte bei.

Beispiele

Einfache Beispiele

Rufen Sie alle Werte, die größer als 1 sind, aus dem Ergebnis Ihrer letzten Abfrage in der aktuellen Sitzung ab:

SELECT $1 AS value FROM VALUES (1), (2), (3);

+-------+
| VALUE |
|-------|
|     1 |
|     2 |
|     3 |
+-------+

SELECT * FROM TABLE(RESULT_SCAN(LAST_QUERY_ID())) WHERE value > 1;

+-------+
| VALUE |
|-------|
|     2 |
|     3 |
+-------+
Copy

Rufen Sie alle Werte aus der vorletzten Abfrage Ihrer aktuellen Sitzung ab:

SELECT * FROM table(RESULT_SCAN(LAST_QUERY_ID(-2)));
Copy

Rufen Sie alle Werte aus der ersten Abfrage Ihrer aktuellen Sitzung ab:

SELECT * FROM table(RESULT_SCAN(LAST_QUERY_ID(1)));
Copy

Rufen Sie die Werte aus der Spalte c2 im Ergebnis der angegebenen Abfrage ab:

SELECT c2 FROM TABLE(RESULT_SCAN('ce6687a4-331b-4a57-a061-02b2b0f0c17c'));
Copy

Beispiele mit den Befehlen DESCRIBE und SHOW

Verarbeiten Sie das Ergebnis eines DESCRIBE USER-Befehls, um bestimmte Themen von Interesse abzurufen (z. B. die Standardrolle eines Benutzers). Hinweis: Da die Ausgabespaltennamen des Befehls DESC USER in Kleinbuchstaben geschrieben wurden, sind in den Befehlen die Spaltennamen in der Abfrage von Notation für Bezeichnertrennung (doppelte Anführungszeichen) umschlossen, damit die Spaltennamen der Abfrage mit den Spaltennamen der überprüften Ausgabe übereinstimmen.

DESC USER jessicajones;
SELECT "property", "value" FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))
  WHERE "property" = 'DEFAULT_ROLE'
  ;
Copy

Verarbeiten Sie das Ergebnis eines SHOW TABLES-Befehls, um leere Tabellen zu extrahieren, die älter als 21 Tage sind: Der Befehl SHOW generiert Spaltennamen in Kleinbuchstaben, sodass der Befehl die Namen in Anführungszeichen setzt und die entsprechende Groß-/Kleinschreibung verwendet:

SHOW TABLES;
-- Show the tables that are more than 21 days old and that are empty
-- (i.e. tables that I might have forgotten about).
SELECT "database_name", "schema_name", "name" as "table_name", "rows", "created_on"
    FROM table(RESULT_SCAN(LAST_QUERY_ID()))
    WHERE "rows" = 0 AND "created_on" < DATEADD(day, -21, CURRENT_TIMESTAMP())
    ORDER BY "created_on";
Copy

Verarbeiten Sie das Ergebnis eines SHOW TABLES-Befehls, um die Tabellen in absteigender Reihenfolge der Größe zu extrahieren. Dieses Beispiel veranschaulicht zudem die Verwendung einer UDF, um die Tabellengröße in einem etwas besser lesbaren Format darzustellen.

-- Show byte counts with suffixes such as "KB", "MB", and "GB".
CREATE OR REPLACE FUNCTION NiceBytes(NUMBER_OF_BYTES INTEGER)
RETURNS VARCHAR
AS
$$
CASE
    WHEN NUMBER_OF_BYTES < 1024
        THEN NUMBER_OF_BYTES::VARCHAR
    WHEN NUMBER_OF_BYTES >= 1024 AND NUMBER_OF_BYTES < 1048576
        THEN (NUMBER_OF_BYTES / 1024)::VARCHAR || 'KB'
   WHEN NUMBER_OF_BYTES >= 1048576 AND NUMBER_OF_BYTES < (POW(2, 30))
       THEN (NUMBER_OF_BYTES / 1048576)::VARCHAR || 'MB'
    ELSE
        (NUMBER_OF_BYTES / POW(2, 30))::VARCHAR || 'GB'
END
$$
;
SHOW TABLES;
-- Show all of my tables in descending order of size.
SELECT "database_name", "schema_name", "name" as "table_name", NiceBytes("bytes") AS "size"
    FROM table(RESULT_SCAN(LAST_QUERY_ID()))
    ORDER BY "bytes" DESC;
Copy

Beispiele für die Verwendung einer gespeicherten Prozedur

Durch Aufrufen einer gespeicherten Prozedur wird ein Wert zurückgegeben. Dieser Wert kann jedoch nicht direkt verarbeitet werden, da der Aufruf einer gespeicherten Prozedur nicht in eine andere Anweisung eingebettet werden kann. Verwenden Sie zur Umgehung dieser Einschränkung RESULT_SCAN, um den von einer gespeicherten Prozedur zurückgegebenen Wert zu verarbeiten. Ein vereinfachtes Beispiel ist unten angegeben:

Erstellen Sie zunächst eine Prozedur, die einen „komplizierten“ Wert zurückgibt (in diesem Fall eine Zeichenfolge mit JSON-kompatiblen Daten), der verarbeitet werden kann, nachdem er von CALL zurückgegeben wurde.

CREATE OR REPLACE PROCEDURE return_JSON()
    RETURNS VARCHAR
    LANGUAGE JavaScript
    AS
    $$
        return '{"keyA": "ValueA", "keyB": "ValueB"}';
    $$
    ;
Copy

Rufen Sie als Nächstes die Prozedur auf:

CALL return_JSON();
+--------------------------------------+
| RETURN_JSON                          |
|--------------------------------------|
| {"keyA": "ValueA", "keyB": "ValueB"} |
+--------------------------------------+
Copy

In den nächsten drei Schritten werden die Daten aus dem Resultset extrahiert.

Rufen Sie die ersten Spalte (und nur diese) ab:

SELECT $1 AS output_col FROM table(RESULT_SCAN(LAST_QUERY_ID()));
+--------------------------------------+
| OUTPUT_COL                           |
|--------------------------------------|
| {"keyA": "ValueA", "keyB": "ValueB"} |
+--------------------------------------+
Copy

Konvertieren Sie die Ausgabe von einem VARCHAR-Wert in ein VARIANT-Wert:

SELECT PARSE_JSON(output_col) AS JSON_COL FROM table(RESULT_SCAN(LAST_QUERY_ID()));
+---------------------+
| JSON_COL            |
|---------------------|
| {                   |
|   "keyA": "ValueA", |
|   "keyB": "ValueB"  |
| }                   |
+---------------------+
Copy

Extrahieren Sie den Wert, der dem Schlüssel „keyB“ entspricht:

SELECT JSON_COL:keyB FROM table(RESULT_SCAN(LAST_QUERY_ID()));
+---------------+
| JSON_COL:KEYB |
|---------------|
| "ValueB"      |
+---------------+
Copy

Hier finden Sie eine kompaktere Möglichkeit, dieselben Daten zu extrahieren, die im vorherigen Beispiel extrahiert wurden. Dieses Beispiel enthält weniger Anweisungen, ist jedoch schwerer zu lesen:

CALL return_JSON();
+--------------------------------------+
| RETURN_JSON                          |
|--------------------------------------|
| {"keyA": "ValueA", "keyB": "ValueB"} |
+--------------------------------------+
SELECT JSON_COL:keyB 
   FROM (
        SELECT PARSE_JSON($1::VARIANT) AS JSON_COL 
            FROM table(RESULT_SCAN(LAST_QUERY_ID()))
        );
+---------------+
| JSON_COL:KEYB |
|---------------|
| "ValueB"      |
+---------------+
Copy

Die Ausgabe von CALL verwendet den Funktionsnamen als Spaltennamen. Beispiel:

+--------------------------------------+
|              RETURN_JSON             |
+--------------------------------------+
| {"keyA": "ValueA", "keyB": "ValueB"} |
+--------------------------------------+
Copy

Wir können diesen Spaltennamen in der Abfrage verwenden. Hier ist eine weitere kompakte Version, in der die Spalte durch den Namen und nicht durch die Spaltennummer referenziert wird:

CALL return_JSON();
+--------------------------------------+
| RETURN_JSON                          |
|--------------------------------------|
| {"keyA": "ValueA", "keyB": "ValueB"} |
+--------------------------------------+
SELECT JSON_COL:keyB
        FROM (
             SELECT PARSE_JSON(RETURN_JSON::VARIANT) AS JSON_COL 
                 FROM table(RESULT_SCAN(LAST_QUERY_ID()))
             );
+---------------+
| JSON_COL:KEYB |
|---------------|
| "ValueB"      |
+---------------+
Copy

Beispiel mit doppelten Spaltennamen

Das folgende Beispiel zeigt, dass RESULT_SCAN effektiv auf alternative Spaltennamen verweist, wenn die ursprüngliche Abfrage doppelte Spaltennamen enthält:

Erstellen Sie zwei Tabellen mit mindestens einer Spalte mit demselben Namen:

CREATE TABLE employees (id INT);
Copy
CREATE TABLE dependents (id INT, employee_id INT);
Copy

Laden Sie Daten in die beiden Tabellen:

INSERT INTO employees (id) VALUES (11);
Copy
INSERT INTO dependents (id, employee_id) VALUES (101, 11);
Copy

Führen Sie nun eine Abfrage aus, für die die Ausgabe zwei gleichnamige Spalten enthält:

SELECT * 
    FROM employees INNER JOIN dependents
        ON dependents.employee_ID = employees.id
    ORDER BY employees.id, dependents.id
    ;
+----+-----+-------------+
| ID |  ID | EMPLOYEE_ID |
|----+-----+-------------|
| 11 | 101 |          11 |
+----+-----+-------------+
Copy

Beachten Sie, dass sich die Ausgabe in Snowsight von der oben gezeigten Ausgabe unterscheidet, da Snowsight doppelte Spaltennamen automatisch verarbeitet.

Rufen Sie jetzt RESULT_SCAN auf, um die Ergebnisse dieser Abfrage zu verarbeiten. Beachten Sie, dass RESULT_SCAN bei Spalten mit demselben Namen im Ergebnis für die erste Spalte den ursprünglichen Namen verwendet, für die zweite Spalte jedoch einen geänderten Namen zuweist, der eindeutig ist. Um eine eindeutigen Namen zu erhalten, hängt RESULT_SCAN das Suffix „_<n>“ an den Namen an, wobei „<n>“ die nächste verfügbare Zahl ist, die einen Namen ergibt, der sich von den Namen der vorherigen Spalten unterscheidet.

SELECT id, id_1, employee_id
    FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))
    WHERE id_1 = 101;
+----+------+-------------+
| ID | ID_1 | EMPLOYEE_ID |
|----+------+-------------|
| 11 |  101 |          11 |
+----+------+-------------+
Copy