- Categorias:
RESULT_SCAN¶
Retorna o conjunto de resultados de um comando anterior (dentro de 24 horas a partir de quando você executou a consulta) como se o resultado fosse uma tabela. Isto é particularmente útil se você quiser processar a saída de qualquer um dos seguintes itens:
Comando SHOW ou DESC[RIBE] que você executou.
Consulte os metadados ou informações de uso da conta, tais como Snowflake Information Schema ou Account Usage.
O resultado de um procedimento armazenado que você chamou de.
O comando/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 detalhes, consulte Uso de resultados de consultas persistentes.
- Consulte também:
DESCRIBE RESULT (DDL de conta e sessão)
Sintaxe¶
RESULT_SCAN ( { '<query_id>' | LAST_QUERY_ID() } )
Argumentos¶
query_id
ouLAST_QUERY_ID()
Ou a ID para uma consulta executada (dentro das últimas 24 horas em qualquer sessão) ou a função LAST_QUERY_ID, que retorna a ID para uma consulta dentro de sua sessão atual.
Notas de uso¶
Se a consulta original for executada manualmente, somente o usuário que executa a consulta original poderá usar a função RESULT_SCAN para processar a saída da consulta. Mesmo um usuário com privilégio ACCOUNTADMIN não pode acessar os resultados da consulta de outro usuário chamando RESULT_SCAN.
Se a consulta original for executada por meio de uma tarefa, a função proprietária da tarefa, em vez de um usuário específico, acionará e executará 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 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 o RESULT_SCAN pode incluir cláusulas, tais como filtros e cláusulas ORDER BY que não estavam na consulta original. Isso permite reduzir ou modificar o conjunto de resultados.
A 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:
- Classic Console:
Em qualquer um dos seguintes locais, clique no link fornecido para exibir/copiar a ID:
- SQL:
Executar uma das seguintes funções:
Função de tabela QUERY_HISTORY , QUERY_HISTORY_BY_*.
Função LAST_QUERY_ID (se a consulta foi executada na sessão atual).
Por exemplo:
SELECT LAST_QUERY_ID(-2);
Note que isto é equivalente a usar LAST_QUERY_ID como a entrada para RESULT_SCAN.
Se RESULT_SCAN processar a saída de consulta que contenha nomes de colunas duplicadas (por exemplo, uma consulta que JOINed duas tabelas que tenham nomes de colunas sobrepostos), então RESULT_SCAN faz referência às colunas duplicadas com nomes modificados, anexando “_1”, “_2” etc. ao nome original. Para obter um exemplo, consulte a seção Exemplos abaixo.
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¶
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); +-------+ | VALUE | |-------| | 1 | | 2 | | 3 | +-------+ SELECT * FROM TABLE(RESULT_SCAN(LAST_QUERY_ID())) WHERE value > 1; +-------+ | 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)));
Recuperar todos os valores de sua primeira consulta na sessão atual:
SELECT * FROM table(RESULT_SCAN(LAST_QUERY_ID(1)));
Recuperar os valores da coluna c2
no resultado da consulta especificada:
SELECT c2 FROM TABLE(RESULT_SCAN('ce6687a4-331b-4a57-a061-02b2b0f0c17c'));
Exemplos usando os comandos DESCRIBE e SHOW¶
Processar o resultado de um comando DESCRIBE USER para recuperar determinados campos de interesse, por exemplo, a função padrão do usuário. Observe que como os nomes das colunas de saída do comando DESC USER
foram gerados em minúsculas, os comandos utilizam notação delimitada do identificador (aspas duplas) em torno dos nomes das colunas na consulta para garantir que os nomes das colunas na consulta correspondam aos nomes das colunas na saída que foi digitalizada.
DESC USER jessicajones; SELECT "property", "value" FROM TABLE(RESULT_SCAN(LAST_QUERY_ID())) WHERE "property" = 'DEFAULT_ROLE' ;
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 e usa a caixa correspondente:
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";
Processe o resultado de um comando SHOW TABLES para extrair as tabelas em ordem decrescente de tamanho. Este exemplo também ilustra o uso de um 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;
Exemplos usando um procedimento armazenado¶
As chamadas de procedimento armazenado retornam um valor. No entanto, este valor não pode ser processado diretamente porque não se 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"}'; $$ ;Em segundo lugar, chamar o procedimento:
CALL return_JSON(); +--------------------------------------+ | 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())); +--------------------------------------+ | OUTPUT_COL | |--------------------------------------| | {"keyA": "ValueA", "keyB": "ValueB"} | +--------------------------------------+Converter a saída de um VARCHAR para uma VARIANT:
SELECT PARSE_JSON(output_col) AS JSON_COL FROM table(RESULT_SCAN(LAST_QUERY_ID())); +---------------------+ | JSON_COL | |---------------------| | { | | "keyA": "ValueA", | | "keyB": "ValueB" | | } | +---------------------+Extrair o valor que corresponde à chave “keyB”:
SELECT JSON_COL:keyB FROM table(RESULT_SCAN(LAST_QUERY_ID())); +---------------+ | JSON_COL:KEYB | |---------------| | "ValueB" | +---------------+
Esta é 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(); +--------------------------------------+ | 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" | +---------------+
A saída do CALL usa o nome da função como o nome da coluna. Por exemplo:
+--------------------------------------+ | RETURN_JSON | +--------------------------------------+ | {"keyA": "ValueA", "keyB": "ValueB"} | +--------------------------------------+
Podemos usar esse nome de coluna na consulta. Aqui está uma versão compacta adicional, na qual a coluna é referenciada pelo nome e não pelo número da coluna:
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" | +---------------+
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);Carregar os dados nas duas tabelas:
INSERT INTO employees (id) VALUES (11);INSERT INTO dependents (id, employee_id) VALUES (101, 11);Agora executar 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 ; +----+-----+-------------+ | ID | ID | EMPLOYEE_ID | |----+-----+-------------| | 11 | 101 | 11 | +----+-----+-------------+Observe que a saída em Snowsight é diferente da saída mostrada acima, pois Snowsight lida com nomes de coluna duplicados automaticamente.
Agora chame RESULT_SCAN para processar os resultados dessa consulta. Observe que, se houver 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, onde «<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; +----+------+-------------+ | ID | ID_1 | EMPLOYEE_ID | |----+------+-------------| | 11 | 101 | 11 | +----+------+-------------+