UDFs SQL tabulaires (UDTFs)¶
Snowflake prend en charge les UDFs SQL qui renvoient un ensemble de lignes, composĂ© de 0, 1, ou de plusieurs lignes, chacune dâentre elles ayant au moins une colonne. Ces UDFs sont appelĂ©es UDFs tabulaires, UDFs de table ou, le plus souvent, UDTFs (fonctions de table dĂ©finies par lâutilisateur).
On peut accĂ©der Ă une UDTF dans la clause FROM dâune requĂȘte.
Dans ce chapitre :
Syntaxe¶
CREATE OR REPLACE FUNCTION <name> ( [ <arguments> ] )
RETURNS TABLE ( <output_col_name> <output_col_type> [, <output_col_name> <output_col_type> ... ] )
AS '<sql_expression>'
Pour une description plus détaillée de la syntaxe générale pour tous les UDFs, y compris les UDTFs SQL, voir CREATE FUNCTION.
Arguments¶
name
:Ce nom dâobjet de base de donnĂ©es doit ĂȘtre valide et respecter les rĂšgles dĂ©crites Ă lâadresse : Exigences relatives Ă lâidentificateur.
arguments
:Il doit sâagir dâune expression, par exemple un nom de colonne, un littĂ©ral ou une expression pouvant correspondre Ă une valeur unique. En rĂšgle gĂ©nĂ©rale, une fonction prend un argument, qui est un nom de colonne. Vous pouvez transmettre plusieurs valeurs, par exemple plusieurs noms de colonne ou un nom de colonne et une ou plusieurs valeurs littĂ©rales.
Il est possible de transmettre une valeur constante ou aucune. Cependant, dans la plupart des cas, si lâentrĂ©e est la mĂȘme Ă chaque fois, la sortie est la mĂȘme Ă chaque fois.
RETURNS TABLE(...)
SpĂ©cifie que lâUDF doit retourner une table. Ă lâintĂ©rieur des parenthĂšses, spĂ©cifiez les paires nom et type des colonnes (comme dĂ©crit ci-dessous) Ă inclure dans la table renvoyĂ©e.
output_col_name
:Le nom dâune colonne de sortie Ă inclure dans la table retournĂ©e. Il doit y avoir au moins une colonne de sortie.
output_col_type
:Le type de données de la colonne de sortie.
sql_expression
:Une expression ou une instruction SQL valide qui renvoient une table avec zéro ou plusieurs lignes, chacune contenant une ou plusieurs colonnes. Les sorties doivent correspondre au nombre et aux types de données spécifiés dans la clause RETURNS.
Notes sur lâutilisation¶
Le corps principal (alias « dĂ©finition ») dâun UDTF SQL doit ĂȘtre une expression SELECT.
Bien que les dĂ©limiteurs autour de lâexpression
sql_expression
soient généralement des guillemets simples, vous pouvez utiliser une paire de signes de dollar$$
comme dĂ©limiteur. Le dĂ©limiteur de fermeture doit correspondre au dĂ©limiteur dâouverture. Une paire de signes dollar est pratique lorsquesql_expression
contient des guillemets simples. Un exemple utilisant des paires de signes dollar est inclus dans la section Exemples ci-dessous.Si le délimiteur est un guillemet simple et que le corps contient un guillemet simple, vous pouvez échapper le guillemet simple dans le corps en utilisant le caractÚre de barre oblique inversée
\
comme caractĂšre dâĂ©chappement. Un exemple est inclus dans la section Exemples ci-dessous.Les colonnes dĂ©finies dans lâUDTF peuvent apparaĂźtre partout oĂč une colonne de table normale peut ĂȘtre utilisĂ©e.
Les types de retours spĂ©cifiĂ©s dans la clause RETURNS dĂ©terminent les noms et les types des colonnes dans les rĂ©sultats tabulaires et doivent correspondre aux types des expressions dans les positions correspondantes de lâinstruction SELECT dans le corps de fonction.
Lorsque vous appelez une UDTF, vous devez inclure le nom de lâUDTF et les arguments entre parenthĂšses aprĂšs le mot-clĂ© TABLE. Pour plus dâinformations, voir Appel dâune UDTF SQL.
Note
Les fonctions tabulaires (UDTFs) ont une limite de 500 arguments dâentrĂ©e et 500 colonnes de sortie.
Appel dâune UDTF SQL¶
Lorsque vous appelez une UDTF dans la clause FROM dâune requĂȘte, spĂ©cifiez le nom et les arguments de lâUDTF Ă lâintĂ©rieur des parenthĂšses qui suivent le mot-clĂ© TABLE.
En dâautres termes, utilisez une forme telle que la suivante pour le mot-clĂ© TABLE lorsque vous appelez une UDTF :
SELECT ...
FROM TABLE ( udtf_name (udtf_arguments) )
Exemples dâUDTFs SQL¶
Exemples de base¶
Ceci est un exemple artificiellement simple dâun UDTF, qui code en dur la sortie. Ceci illustre Ă©galement lâutilisation de $$
comme délimiteur :
CREATE FUNCTION t()
RETURNS TABLE(msg VARCHAR)
AS
$$
SELECT 'Hello'
UNION
SELECT 'World'
$$;
SELECT msg
FROM TABLE(t())
ORDER BY msg;
+-------+
| MSG |
|-------|
| Hello |
| World |
+-------+
Cet exemple est similaire Ă lâexemple prĂ©cĂ©dent, mais il utilise des guillemets simples comme dĂ©limiteur, et utilise le caractĂšre dâĂ©chappement \
pour Ă©chapper les guillemets simples dans le corps de lâUDTF :
CREATE FUNCTION t()
RETURNS TABLE(msg VARCHAR)
AS
'
SELECT \'Hello\'
UNION
SELECT \'World\'
';
SELECT msg
FROM TABLE(t())
ORDER BY msg;
+-------+
| MSG |
|-------|
| Hello |
| World |
+-------+
Ceci est un autre exemple de base dâun UDTF. Il interroge une table et retourne deux des colonnes de cette table :
create or replace table orders (
product_id varchar,
quantity_sold numeric(11, 2)
);
insert into orders (product_id, quantity_sold) values
('compostable bags', 2000),
('re-usable cups', 1000);
create or replace function orders_for_product(PROD_ID varchar)
returns table (Product_ID varchar, Quantity_Sold numeric(11, 2))
as
$$
select product_ID, quantity_sold
from orders
where product_ID = PROD_ID
$$
;
select product_id, quantity_sold
from table(orders_for_product('compostable bags'))
order by product_id;
+------------------+---------------+
| PRODUCT_ID | QUANTITY_SOLD |
|------------------+---------------|
| compostable bags | 2000.00 |
+------------------+---------------+
Cette mĂȘme fonctionnalitĂ© peut Ă©galement ĂȘtre implĂ©mentĂ©e Ă lâaide dâune vue.
Exemples avec jointures¶
Créer et utiliser un UDTF SQL qui renvoie des informations de pays (COUNTRY_CODE
et COUNTRY_NAME
) pour lâID dâun utilisateur spĂ©cifiĂ© :
create or replace table countries (country_code char(2), country_name varchar);
insert into countries (country_code, country_name) values
('FR', 'FRANCE'),
('US', 'UNITED STATES'),
('ES', 'SPAIN');
create or replace table user_addresses (user_ID integer, country_code char(2));
insert into user_addresses (user_id, country_code) values
(100, 'ES'),
(123, 'FR'),
(123, 'US');
CREATE OR REPLACE FUNCTION get_countries_for_user ( id number )
RETURNS TABLE (country_code char, country_name varchar)
AS 'select distinct c.country_code, c.country_name
from user_addresses a, countries c
where a.user_id = id
and c.country_code = a.country_code';
select *
from table(get_countries_for_user(123)) cc
where cc.country_code in ('US','FR','CA')
order by country_code;
+--------------+---------------+
| COUNTRY_CODE | COUNTRY_NAME |
|--------------+---------------|
| FR | FRANCE |
| US | UNITED STATES |
+--------------+---------------+
CrĂ©er un UDTF SQL qui renvoie la couleur prĂ©fĂ©rĂ©e dâune annĂ©e spĂ©cifiĂ©e :
create or replace table favorite_years as
select 2016 year
UNION ALL
select 2017
UNION ALL
select 2018
UNION ALL
select 2019;
create or replace table colors as
select 2017 year, 'red' color, true favorite
UNION ALL
select 2017 year, 'orange' color, true favorite
UNION ALL
select 2017 year, 'green' color, false favorite
UNION ALL
select 2018 year, 'blue' color, true favorite
UNION ALL
select 2018 year, 'violet' color, true favorite
UNION ALL
select 2018 year, 'brown' color, false favorite;
create or replace table fashion as
select 2017 year, 'red' fashion_color
UNION ALL
select 2018 year, 'black' fashion_color
UNION ALL
select 2019 year, 'orange' fashion_color;
create or replace function favorite_colors(the_year int)
returns table(color string) as
'select color from colors where year=the_year and favorite=true';
Utilisez lâUDTF dans une requĂȘte :
select color
from table(favorite_colors(2017))
order by color;
+--------+
| COLOR |
|--------|
| orange |
| red |
+--------+
Utilisez lâUDTF dans une jointure avec une autre table ; notez que la colonne de jointure de la table est transmise comme argument Ă la fonction.
select *
from favorite_years y join table(favorite_colors(y.year)) c
order by year, color;
+------+--------+
| YEAR | COLOR |
|------+--------|
| 2017 | orange |
| 2017 | red |
| 2018 | blue |
| 2018 | violet |
+------+--------+
Utilisez une clause WHERE, plutÎt que ON, pour des prédicats supplémentaires :
select *
from fashion f join table(favorite_colors(f.year)) fav
where fav.color = f.fashion_color ;
+------+---------------+-------+
| YEAR | FASHION_COLOR | COLOR |
|------+---------------+-------|
| 2017 | red | red |
+------+---------------+-------+
Utilisez lâUDTF avec une constante dans une expression de jointure ; notez quâune clause WHERE, plutĂŽt que ON, doit ĂȘtre utilisĂ©e pour des conditions de jointure supplĂ©mentaires :
select fav.color as favorite_2017, f.*
from fashion f JOIN table(favorite_colors(2017)) fav
where fav.color = f.fashion_color
order by year;
+---------------+------+---------------+
| FAVORITE_2017 | YEAR | FASHION_COLOR |
|---------------+------+---------------|
| red | 2017 | red |
| orange | 2019 | orange |
+---------------+------+---------------+