Categorias:

Funções de tabela

RESULT_SCAN

Retorna o conjunto de resultados de um comando anterior (até 24 horas após a execução da consulta) como se o resultado fosse uma tabela. Essa função é útil principalmente se você quiser processar a saída a partir de alguma das seguintes operações:

O comando ou consulta pode ser da sessão atual ou de qualquer outra sessão, incluindo sessões passadas, desde que o período de 24 horas não tenha transcorrido. Este período não é ajustável. Para obter mais informações, consulte Uso de resultados de consultas persistentes.

Dica

Você pode usar o operador de canal (->>) em vez desta função para processar os resultados de um comando anterior.

Consulte também:

DESCRIBE RESULT (DDL de conta e sessão)

Sintaxe

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

Argumentos

'query_id' ou query_index ou LAST_QUERY_ID()

Uma especificação de uma consulta executada nas últimas 24 horas em qualquer sessão, um índice inteiro de uma consulta na sessão atual ou a função LAST_QUERY_ID, que retorna o ID de uma consulta dentro de sua sessão atual.

IDs de consulta Snowflake são cadeias de caracteres exclusivas que se assemelham a 01b71944-0001-b181-0000-0129032279f6.

Os índices de consulta são relativos à primeira consulta na sessão atual (se positiva) ou à consulta mais recente (se negativa). Por exemplo, RESULT_SCAN(-1) é equivalente a RESULT_SCAN(LAST_QUERY_ID()).

Este argumento é opcional. Se for omitido, o padrão é RESULT_SCAN(-1), que retorna o conjunto de resultados do comando mais recente.

Notas de uso

  • Se a consulta original foi executada manualmente, somente o usuário que executou a consulta original pode usar a função RESULT_SCAN para processar a saída da consulta. Mesmo um usuário com o privilégio ACCOUNTADMIN não pode acessar os resultados da consulta de outro usuário chamando RESULT_SCAN.

  • Se a consulta original foi executada usando uma tarefa, a função que possui a tarefa, em vez de um usuário específico, acionou e executou a consulta. Se um usuário ou tarefa estiver operando com a mesma função, ele poderá usar RESULT_SCAN para acessar os resultados da consulta.

  • O Snowflake armazena todos os resultados das consultas por 24 horas. Esta função só retorna resultados para consultas que foram executadas dentro deste período.

  • Os conjuntos de resultados não têm metadados associado a eles, portanto, o processamento de grandes resultados pode ser mais lento do que se você estivesse consultando uma tabela real.

  • A consulta contendo RESULT_SCAN pode incluir cláusulas, como filtros e cláusulas ORDER BY que não estavam na consulta original. Você pode usar essas cláusulas para reduzir ou modificar o conjunto de resultados.

  • Uma RESULT_SCAN não garante retornar as linhas na mesma ordem em que a consulta original retornou as linhas. Você pode incluir uma cláusula ORDER BY com a consulta RESULT_SCAN para especificar uma ordem específica.

  • Para recuperar a ID para uma consulta específica, use qualquer um dos seguintes métodos:

    Snowsight:

    Em qualquer um dos seguintes locais, clique no link fornecido para exibir/copiar o ID:

    • Em Worksheets sob Projects, após executar uma consulta, a opção Query Details inclui um link para o ID.

    • Em Query History sob Monitoring, cada consulta inclui o ID como um link.

    SQL:

    Chame uma das seguintes funções:

  • Se RESULT_SCAN processar a saída de consulta que continha nomes de colunas duplicadas (por exemplo, uma consulta que uniu duas tabelas que têm nomes de colunas sobrepostos), então RESULT_SCAN fará referência às colunas duplicadas com nomes modificados, anexando _1, _2, e assim por diante ao nome original. Para obter um exemplo, consulte o seguinte a seção Exemplos.

  • Os carimbos de data/hora em arquivos Parquet consultados usando o verificador vetorizado às vezes exibem a hora em um fuso horário diferente. Use a função CONVERT_TIMEZONE para converter para um fuso horário padrão para todos os dados de carimbo de data/hora.

Detalhes do agrupamento

Quando RESULT_SCAN retorna os resultados da instrução anterior, RESULT_SCAN preserva a(s) especificação(ões) de agrupamento dos valores que retorna.

Exemplos

Os exemplos a seguir usam a função RESULT_SCAN.

Exemplos simples

Recuperar todos os valores maiores que 1 do resultado de sua consulta mais recente na sessão atual:

SELECT $1 AS value FROM VALUES (1), (2), (3);
Copy
+-------+
| VALUE |
|-------|
|     1 |
|     2 |
|     3 |
+-------+
SELECT * FROM TABLE(RESULT_SCAN(LAST_QUERY_ID())) WHERE value > 1;
Copy
+-------+
| VALUE |
|-------|
|     2 |
|     3 |
+-------+

Recuperar todos os valores de sua segunda consulta mais recente na sessão atual:

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

Recuperar todos os valores de sua primeira consulta na sessão atual:

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

Recuperar os valores da coluna c2 no resultado da consulta especificada:

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

Exemplos usando os comandos DESCRIBE e SHOW

Processar o resultado de um comando DESCRIBE USER para recuperar determinados campos de interesse, como a função padrão do usuário. Como os nomes das colunas de saída do comando DESC USER foram gerados em minúsculas, os comandos usavam identificadores entre aspas duplas nos nomes das colunas na consulta para garantir que esses nomes correspondam aos nomes das colunas na saída que foi verificada.

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

Processe o resultado de um comando SHOW TABLES para extrair tabelas vazias com mais de 21 dias. O comando SHOW gera nomes de colunas em letras minúsculas, então o comando coloca os nomes entre aspas para usar a caixa correspondente:

SHOW TABLES;
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

Processe o resultado de um comando SHOW TABLES para extrair as tabelas em ordem decrescente de tamanho. O exemplo a seguir também mostra como usar uma UDF para mostrar o tamanho da tabela em um formato um pouco mais legível para o ser humano:

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

Exemplos usando um procedimento armazenado

As chamadas de procedimento armazenado retornam um valor. No entanto, esse valor não pode ser processado diretamente porque você não pode incorporar uma chamada de procedimento armazenado em outra instrução. Para contornar esta limitação, você pode usar RESULT_SCAN para processar o valor retornado por um procedimento armazenado. Um exemplo simplificado está abaixo:

Primeiro, criar um procedimento que retorna um valor “complicado” (neste caso, uma cadeia de caracteres que contenha dados compatíveis com JSON) que possa ser processado após retornar de CALL.

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

Chame o procedimento:

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

As três etapas seguintes extraem os dados do conjunto de resultados.

Obter a primeira (e única) coluna:

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

Conversão da saída de um valor VARCHAR para um valor VARIANT:

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

Extraia o valor que corresponde à chave keyB:

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

O exemplo a seguir mostra uma maneira mais compacta de extrair os mesmos dados que foram extraídos no exemplo anterior. Este exemplo tem menos instruções, mas é mais difícil de ler:

CALL return_json();
Copy
+--------------------------------------+
| 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()))
      );
Copy
+---------------+
| JSON_COL:KEYB |
|---------------|
| "ValueB"      |
+---------------+

A saída do CALL usa o nome da função como o nome da coluna. Você pode usar esse nome de coluna na consulta. O exemplo a seguir mostra uma versão compacta adicional, na qual a coluna é referenciada pelo nome em vez do número da coluna:

CALL return_json();
Copy
+--------------------------------------+
| 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()))
       );
Copy
+---------------+
| JSON_COL:KEYB |
|---------------|
| "ValueB"      |
+---------------+

Exemplo com nomes de colunas duplicadas

O exemplo a seguir mostra que RESULT_SCAN efetivamente faz referência a nomes de colunas alternativas quando há nomes de colunas duplicadas na consulta original:

Criar duas tabelas que tenham pelo menos uma coluna com o mesmo nome:

CREATE TABLE employees (id INT);

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

Carregar os dados nas duas tabelas:

INSERT INTO employees (id) VALUES (11);

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

Agora execute uma consulta para a qual a saída conterá duas colunas com o mesmo nome:

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

Agora chame RESULT_SCAN para processar os resultados dessa consulta. Se colunas diferentes com o mesmo nome nos resultados, RESULT_SCAN usa o nome original para a primeira coluna e atribui à segunda coluna um nome modificado que é exclusivo. Para tornar o nome exclusivo, RESULT_SCAN acrescenta o sufixo _n ao nome, em qe n é o próximo número disponível que produz um nome diferente dos nomes das colunas anteriores.

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