Solução de problemas em UDFs de SQL

Este tópico fornece informações de solução de problemas sobre UDFs (funções definidas pelo usuário) de SQL.

Neste tópico:

Solução de problemas

Dicas

Se você usar uma UDF de SQL em uma política de mascaramento, certifique-se de que o tipo de dados da coluna, a UDF e a política de mascaramento sejam correspondentes.

Mensagem de erro: Unsupported subquery type

Causa

Se uma UDF contém uma expressão de consulta, a UDF pode atuar como uma subconsulta. Se uma subconsulta recebe um nome de coluna, a subconsulta pode atuar como uma subconsulta correlacionada. Se uma subconsulta correlacionada viola as regras do Snowflake para subconsultas correlacionadas, o usuário recebe a mensagem de erro Unsupported subquery type. O exemplo abaixo mostra uma subconsulta correlacionada inválida, e como uma UDF pode agir como uma subconsulta correlacionada inválida semelhante.

Crie um par de tabelas e carregue dados nelas:

CREATE TABLE stores (store_ID INTEGER, city VARCHAR);
CREATE TABLE employee_sales (employee_ID INTEGER, store_ID INTEGER, sales NUMERIC(10,2), 
    sales_date DATE);
INSERT INTO stores (store_ID, city) VALUES 
    (1, 'Winnipeg'),
    (2, 'Toronto');
INSERT INTO employee_sales (employee_ID, store_ID, sales, sales_date) VALUES 
    (1001, 1, 9000.00, '2020-01-27'),
    (1002, 1, 2000.00, '2020-01-27'),
    (2001, 2, 6000.00, '2020-01-27'),
    (2002, 2, 4000.00, '2020-01-27'),
    (2002, 2, 5000.00, '2020-01-28')
    ;
Copy

A seguinte instrução SQL contém uma subconsulta correlacionada que não segue as regras do Snowflake. Esse código causa um erro Unsupported subquery type:

SELECT employee_ID,
       store_ID,
       (SELECT city FROM stores WHERE stores.store_ID = employee_sales.store_ID)
    FROM employee_sales;
Copy

O código abaixo cria e depois chama uma UDF que age como subconsulta de forma a criar uma subconsulta correlacionada semelhante à mostrada acima:

CREATE FUNCTION subquery_like_udf(X INT)
    RETURNS VARCHAR
    LANGUAGE SQL
    AS
    $$
        SELECT city FROM stores WHERE stores.store_ID = X
    $$;
Copy
SELECT employee_ID, subquery_like_udf(employee_sales.store_ID)
    FROM employee_sales;
Copy
Solução nº 1

Se a UDF contém uma expressão de consulta, somente chame a UDF de forma consistente com as regras para subconsultas.

Por exemplo, a instrução a seguir chama a UDF com uma constante e não com um nome de coluna. Portanto, a UDF não age como uma subconsulta correlacionada:

SELECT subquery_like_udf(1);
+----------------------+
| SUBQUERY_LIKE_UDF(1) |
|----------------------|
| Winnipeg             |
+----------------------+
Copy
Solução nº 2

Em alguns casos, você pode reescrever a UDF para alcançar o mesmo objetivo de maneira diferente. Uma subconsulta correlacionada é permitida se é possível determinar estaticamente que a subconsulta retornará uma linha. A UDF a seguir usa uma função agregada e, portanto, retorna apenas uma linha:

CREATE FUNCTION subquery_like_udf_2(X INT)
    RETURNS VARCHAR
    LANGUAGE SQL
    AS
    $$
        SELECT ANY_VALUE(city) FROM stores WHERE stores.store_ID = X
    $$;
Copy
SELECT employee_ID, sales_date, subquery_like_udf_2(employee_sales.store_ID)
    FROM employee_sales
    ORDER BY employee_ID, sales_date;
+-------------+------------+----------------------------------------------+
| EMPLOYEE_ID | SALES_DATE | SUBQUERY_LIKE_UDF_2(EMPLOYEE_SALES.STORE_ID) |
|-------------+------------+----------------------------------------------|
|        1001 | 2020-01-27 | Winnipeg                                     |
|        1002 | 2020-01-27 | Winnipeg                                     |
|        2001 | 2020-01-27 | Toronto                                      |
|        2002 | 2020-01-27 | Toronto                                      |
|        2002 | 2020-01-28 | Toronto                                      |
+-------------+------------+----------------------------------------------+
Copy