์ค์นผ๋ผ SQL UDFsยถ
์ด ํญ๋ชฉ์์๋ SQL UDF(์ฌ์ฉ์ ์ ์ ํจ์)์ ๊ด๋ จ๋ ๊ฐ๋ ๋ฐ ์ฌ์ฉ ์ธ๋ถ ์ ๋ณด๋ฅผ ๋ค๋ฃน๋๋ค.
์ด ํญ๋ชฉ์ ๋ด์ฉ:
์ผ๋ฐ ์ฌ์ฉยถ
SQL UDF๋ ์์์ SQL ์์ ํ๊ฐํ๊ณ ์์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํฉ๋๋ค.
ํจ์ ์ ์๋ ์ค์นผ๋ผ(์ฆ, ๋จ์ผ) ๊ฐ์ ๋ฐํํ๊ฑฐ๋, ํ ์ด๋ธ ํจ์๋ก ์ ์๋ ๊ฒฝ์ฐ ํ ์ธํธ๋ฅผ ๋ฐํํ๋ SQL ์์ผ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๋ค์์ ์์ ๋ฉด์ ์ ๊ณ์ฐํ๋ ์ค์นผ๋ผ UDF์ ๊ธฐ๋ณธ ์์ ๋๋ค.
CREATE FUNCTION area_of_circle(radius FLOAT)
RETURNS FLOAT
AS
$$
pi() * radius * radius
$$
;
SELECT area_of_circle(1.0);
์ถ๋ ฅ:
SELECT area_of_circle(1.0);
+---------------------+
| AREA_OF_CIRCLE(1.0) |
|---------------------|
| 3.141592654 |
+---------------------+
์์ ์ฟผ๋ฆฌ ์(SELECT ์)์ผ ์ ์์ต๋๋ค. ์:
CREATE FUNCTION profit()
RETURNS NUMERIC(11, 2)
AS
$$
SELECT SUM((retail_price - wholesale_price) * number_sold)
FROM purchases
$$
;
SQL UDF์์ ์ฟผ๋ฆฌ ์์ ์ฌ์ฉํ ๋๋ ์ฟผ๋ฆฌ ์์ ์ข ๋ฃํ๊ธฐ ์ํด UDF ๋ณธ๋ฌธ์ ์ธ๋ฏธ์ฝ๋ก ์ ํฌํจํ์ง ๋ง์ญ์์ค.
ํ๋์ ์ฟผ๋ฆฌ ์๋ง ํฌํจํ ์ ์์ต๋๋ค. ์์๋ UNION [ALL]์ด ํฌํจ๋ ์ ์์ต๋๋ค.
์ฐธ๊ณ
UDF์ ๋ณธ๋ฌธ์ ์์ ํ SELECT ๋ฌธ์ ํฌํจํ ์ ์์ง๋ง, DDL ๋ฌธ์ด๋ SELECT ์ด์ธ์ DML ๋ฌธ์ ํฌํจํ ์ ์์ต๋๋ค.
์ฐธ๊ณ
์ค์นผ๋ผ ํจ์(UDF)์ ์ ๋ ฅ ์ธ์๋ 500๊ฐ๋ก ์ ํ๋ฉ๋๋ค.
๋ฉ๋ชจ์ด์ ์ด์ ๊ฐ๋ฅ UDFยถ
์ค์นผ๋ผ SQL UDF๋ ๋ฉ๋ชจ์ด์ ์ด์ ๊ฐ๋ฅํ ์ ์์ต๋๋ค. ๋ฉ๋ชจ์ด์ ์ด์ ๊ฐ๋ฅ ํจ์๋ ์ค์นผ๋ผ SQL UDF๋ฅผ ํธ์ถํ ๊ฒฐ๊ณผ๋ฅผ ์บ์ํ๋ค๊ฐ ๋์ค์ ์ถ๋ ฅ์ด ํ์ํ ๋ ์บ์๋ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํฉ๋๋ค. ๋ฉ๋ชจ์ด์ ์ด์ ๊ฐ๋ฅ ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ํ ์ก์ธ์ค ์ ์ฑ ๋๋ ๋ง์คํน ์ ์ฑ ๋ด์์ ์ฐธ์กฐ๋๋ ๋งคํ ํ ์ด๋ธ ์ ์ฌ๋ฌ ์ด ์กฐํ์ ๊ฐ์ ๋ณต์กํ ์ฟผ๋ฆฌ์ ์ฑ๋ฅ์ด ํฅ์๋๋ค๋ ์ด์ ์ด ์์ต๋๋ค.
์ ์ฑ ์์ ์(์: ํ ์ก์ธ์ค ์ ์ฑ ์ ๋ํ OWNERSHIP ๊ถํ์ด ์๋ ์ญํ )๋ ๋ฉ๋ชจ์ด์ ์ด์ ๊ฐ๋ฅ ํจ์์ด ์๋ ๋งคํ ํ ์ด๋ธ์ด ์๋ ํ์ ์ฟผ๋ฆฌ๋ฅผ ๋์ฒดํ๋๋ก ์ ์ฑ ์กฐ๊ฑด์ ์ ๋ฐ์ดํธํ ์ ์์ต๋๋ค. ์ฌ์ฉ์๊ฐ ๋์ค์ ์ฟผ๋ฆฌ์์ ์ ์ฑ ์ผ๋ก ๋ณดํธ๋ ์ด์ ์ฐธ์กฐํ ๋ ๋ฉ๋ชจ์ด์ ์ด์ ๊ฐ๋ฅ ํจ์์์ ์บ์๋ ๊ฒฐ๊ณผ๋ฅผ ํ์์ ๋ฐ๋ผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋ฉ๋ชจ์ด์ ์ด์ ๊ฐ๋ฅ ํจ์ ๋ง๋ค๊ธฐยถ
MEMOIZABLE
ํค์๋๋ฅผ ์ง์ ํ์ฌ CREATE FUNCTION ๋ฌธ์์ ๋ฉ๋ชจ์ด์ ์ด์
๊ฐ๋ฅํ๋๋ก ์ค์นผ๋ผ SQL UDF๋ฅผ ์ ์ํ ์ ์์ต๋๋ค. ์ธ์์ ์ ๋ฌด์ ๊ด๊ณ์์ด ๋ฉ๋ชจ์ด์ ์ด์
๊ฐ๋ฅ ํจ์๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค. ์ธ์๋ฅผ ์ฌ์ฉํ๋ฉด SQL UDF๋ฅผ ๋ ์์ ๋กญ๊ฒ ์ ์ํ ์ ์์ต๋๋ค. ๋ฉ๋ชจ์ด์ ์ด์
๊ฐ๋ฅ ํจ์๋ฅผ ํธ์ถํ๋ ์ ์ฑ
์ ์์ฑํ๋ฉด ์ ์ฑ
์ ์ ์ํ๋ ๋ฐฉ๋ฒ ์ธก๋ฉด์์ ์ ์ฐ์ฑ์ด ์ฆ๊ฐํฉ๋๋ค.
์ธ์๋ฅผ ์ง์ ํ๋ ๊ฒฝ์ฐ ์ธ์๋ ๋ค์ ๋ฐ์ดํฐ ํ์ ์ค ํ๋๋ฅผ ๊ฐ๋ ์์ ๊ฐ์ด์ด์ผ ํฉ๋๋ค.
VARCHAR ๋ฐ ๊ธฐํ ๋ฌธ์์ด ๋ฐ์ดํฐ ํ์ .
NUMBER ๋ฐ ๊ธฐํ ์ซ์ํ ๋ฐ์ดํฐ ํ์ .
TIMESTAMP ๋ฐ ๊ธฐํ ๋ ์ง ๋ฐ์ดํฐ ํ์ .
BOOLEAN.
๋ฐ์ ํ ๋ฐ์ดํฐ ํ์ ๋ฐ ํ ์ด๋ธ ์ด๊ณผ ๊ฐ์ ์์๊ฐ ์๋ ๊ฐ๊ณผ ํด๋น ๋ฐ์ดํฐ ํ์ ์ ์ง์๋์ง ์์ต๋๋ค.
๋ฉ๋ชจ์ด์ ์ด์ ๊ฐ๋ฅ ํจ์๋ฅผ ์์ฑํ ๋์ ์ง์นจ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
BOOLEAN ๋๋ ๋ค๋ฅธ ์ค์นผ๋ผ ๋ฐ์ดํฐ ํ์ ์
result_data_type
์ผ๋ก ์ง์ ํฉ๋๋ค.์บ์ ํฌ๊ธฐ์ ์ ํ์ด ์์ผ๋ฏ๋ก ARRAY๋ฅผ
result_data_type
์ผ๋ก ์ง์ ํ ๋๋ ์ฃผ์ํ์ญ์์ค.OBJECT ๋ฐ VARIANT์ ๊ฐ์ ๋ค๋ฅธ ๋ฐ์ดํฐ ํ์ ์ ์ง์ ํ์ง ๋ง์ญ์์ค.
์ด๋ค ๋ฐฉ์์ผ๋ก๋ ๋ค๋ฅธ ๋ฉ๋ชจ์ด์ ์ด์ ๊ฐ๋ฅ ํจ์๋ฅผ ์ฐธ์กฐํ์ง ๋ง์ญ์์ค.
๋ฉ๋ชจ์ด์ ์ด์ ๊ฐ๋ฅ ํจ์ ํธ์ถํ๊ธฐยถ
๋ฉ๋ชจ์ด์ ์ด์ ๊ฐ๋ฅ ํจ์๋ SELECT ๋ฌธ์์ ํธ์ถํ๊ฑฐ๋ ์ ์ฑ ์ ์์ ํฌํจ๋ ์ ์์ผ๋ฉฐ, ์ด์ฒ๋ผ ํฌํจํ ๋ค์์ ์ ์ฑ ์กฐ๊ฑด์ ๋ฐ๋ผ ๋ฉ๋ชจ์ด์ ์ด์ ๊ฐ๋ฅ ํจ์๋ฅผ ํธ์ถํ๊ฒ ๋ฉ๋๋ค.
๋ฉ๋ชจ์ด์ ์ด์ ๊ฐ๋ฅ ํจ์๋ฅผ ํธ์ถํ ๋๋ ๋ค์ ์ฌํญ์ ์ ์ํ์ญ์์ค.
ARRAY ๋ฐ์ดํฐ ํ์ ์ ๋ฐํํ๊ฑฐ๋ ์ค์นผ๋ผ๊ฐ ์๋ ๊ฐ์ ์ง์ ํ๋ SQL UDF์ ๊ฒฝ์ฐ ๋ฉ๋ชจ์ด์ ์ด์ ๊ฐ๋ฅ ํจ์๋ฅผ ARRAY_CONTAINS ํจ์์ ์ธ์๋ก ์ฌ์ฉํฉ๋๋ค.
์บ์ ํฌ๊ธฐ ์ ํ:
๊ฐ ๋ฉ๋ชจ์ด์ ์ด์ ๊ฐ๋ฅ ํจ์๋ ํ์ฌ Snowflake ์ธ์ ์ ๋ํด 10KB๋ก ์ ํ๋ฉ๋๋ค.
๋ฉ๋ชจ์ด์ ์ด์ ๊ฐ๋ฅ ํจ์๊ฐ ๊ฒฐ๊ณผ ์ธํธ ์บ์์ ๋ํ ์ด ์ ํ์ ์ด๊ณผํ ๊ฒฝ์ฐ Snowflake๋ ๋ฉ๋ชจ์ด์ ์ด์ ๊ฐ๋ฅ ํจ์๋ฅผ ํธ์ถํ ๊ฒฐ๊ณผ๋ฅผ ์บ์ํ์ง ์์ต๋๋ค. ๋์ UDF์ ํจ์์ ์์ฑ ๋ฐฉ์์ ๋ฐ๋ผ ์ผ๋ฐ ์ค์นผ๋ผ UDF๋ก ์๋ํฉ๋๋ค.
์บ์ ์ฌ์ฉ๋:
๋ฉ๋ชจ์ด์ ์ด์ ๊ฐ๋ฅ ํจ์์๋ ์ฟผ๋ฆฌ ํ๊ฒฝ๊ณผ ์ปจํ ์คํธ๊ฐ ๋ณ๊ฒฝ๋์ง ์์ ๋ ๋ค๋ฅธ SQL ๋ฌธ์ ๋ํด ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ๊ฒฐ๊ณผ ์บ์๊ฐ ์์ต๋๋ค. ์ผ๋ฐ์ ์ผ๋ก, ์ด๋ ๊ฒฐ๊ณผ ์บ์๊ฐ ๋ค์๊ณผ ๊ฐ์ ๊ฒฝ์ฐ์ ๋ค๋ฅธ SQL ๋ฌธ์ ์ ์ฉ๋จ์ ์๋ฏธํฉ๋๋ค.
์ฟผ๋ฆฌ์์ ์ฐธ์กฐ๋๋ ์ค๋ธ์ ํธ์ ์ด์ ๋ํ ์ก์ธ์ค ์ ์ด ๊ถํ์ ๋์ผํ๊ฒ ์ ์ง๋ฉ๋๋ค.
์ฟผ๋ฆฌ์์ ์ฐธ์กฐ๋ ์ค๋ธ์ ํธ๋ ์์ ๋์ง ์์ต๋๋ค(์: DML ๋ฌธ์ ํตํด).
Account Usage QUERY_HISTORY ๋ทฐ์ CHILD_QUERIES_WAIT_TIME ์ด์ ๋ฉ๋ชจ์ด์ ์ด์ ๊ฐ๋ฅ ํจ์๋ฅผ ํธ์ถํ ๋ ์บ์๋ ์กฐํ๋ฅผ ์๋ฃํ๋ ๋ฐ ๊ฑธ๋ฆฌ๋ ์๊ฐ(๋ฐ๋ฆฌ์ด)์ ๊ธฐ๋กํฉ๋๋ค.
๋ค์๊ณผ ๊ฐ์ ๊ฒฝ์ฐ์๋ ๋ฉ๋ชจ์ด์ ์ด์ ๊ฐ๋ฅ ํจ์๊ฐ ์บ์๋ ๊ฒฐ๊ณผ๋ฅผ ์ฌ์ฌ์ฉํ์ง ์์ต๋๋ค.
ํจ์๊ฐ ํ ์ด๋ธ ๋๋ ๊ธฐํ ์ค๋ธ์ ํธ๋ฅผ ์ฐธ์กฐํ๊ณ ์ฐธ์กฐ๋ ํ ์ด๋ธ์ ๋ํ ์ ๋ฐ์ดํธ๊ฐ ์๋ ๊ฒฝ์ฐ.
ํ ์ด๋ธ์ ๋ํ ์ก์ธ์ค ์ ์ด์ ๋ณํ๊ฐ ์๋ ๊ฒฝ์ฐ.
ํจ์๊ฐ ๋น๊ฒฐ์ ์ ํจ์๋ฅผ ํธ์ถํ๋ ๊ฒฝ์ฐ.
ํจ์๊ฐ ์ธ๋ถ ํจ์ ๋๋ SQL UDF๊ฐ ์๋ UDF๋ฅผ ํธ์ถํ๋ ๊ฒฝ์ฐ.
์ยถ
๊ธฐ๋ณธ SQL ์ค์นผ๋ผ UDF ์ยถ
์ด ์๋ ์ํ ์์ pi์ ํ๋ ์ฝ๋ฉ๋ ๊ทผ์ฟ๊ฐ์ ๋ฐํํฉ๋๋ค.
CREATE FUNCTION pi_udf()
RETURNS FLOAT
AS '3.141592654::FLOAT'
;
SELECT pi_udf();
์ถ๋ ฅ:
SELECT pi_udf();
+-------------+
| PI_UDF() |
|-------------|
| 3.141592654 |
+-------------+
์ผ๋ฐ SQL ์ยถ
SELECT ๋ฌธ์ ํฌํจํ ์ฟผ๋ฆฌ ์ยถ
๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ํ ์ด๋ธ๊ณผ ๋ฐ์ดํฐ๋ฅผ ๋ง๋์ญ์์ค.
CREATE TABLE purchases (number_sold INTEGER, wholesale_price NUMBER(7,2), retail_price NUMBER(7,2));
INSERT INTO purchases (number_sold, wholesale_price, retail_price) VALUES
(3, 10.00, 20.00),
(5, 100.00, 200.00)
;
UDF๋ฅผ ๋ง๋ญ๋๋ค.
CREATE FUNCTION profit()
RETURNS NUMERIC(11, 2)
AS
$$
SELECT SUM((retail_price - wholesale_price) * number_sold)
FROM purchases
$$
;
๋ค์๊ณผ ๊ฐ์ด ์ฟผ๋ฆฌ์์ UDF๋ฅผ ํธ์ถํ์ญ์์ค.
SELECT profit();
์ถ๋ ฅ:
SELECT profit();
+----------+
| PROFIT() |
|----------|
| 530.00 |
+----------+
WITH ์ ์ UDFยถ
CREATE TABLE circles (diameter FLOAT);
INSERT INTO circles (diameter) VALUES
(2.0),
(4.0);
CREATE FUNCTION diameter_to_radius(f FLOAT)
RETURNS FLOAT
AS
$$ f / 2 $$
;
WITH
radii AS (SELECT diameter_to_radius(diameter) AS radius FROM circles)
SELECT radius FROM radii
ORDER BY radius
;
์ถ๋ ฅ:
+--------+
| RADIUS |
|--------|
| 1 |
| 2 |
+--------+
JOIN ์์ ยถ
์ด ์์์๋ JOIN ์์ ์ ํฌํจํ๋ ๋ ๋ณต์กํ ์ฟผ๋ฆฌ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ํ ์ด๋ธ๊ณผ ๋ฐ์ดํฐ๋ฅผ ๋ง๋์ญ์์ค.
CREATE TABLE orders (product_ID varchar, quantity integer, price numeric(11, 2), buyer_info varchar);
CREATE TABLE inventory (product_ID varchar, quantity integer, price numeric(11, 2), vendor_info varchar);
INSERT INTO inventory (product_ID, quantity, price, vendor_info) VALUES
('X24 Bicycle', 4, 1000.00, 'HelloVelo'),
('GreenStar Helmet', 8, 50.00, 'MellowVelo'),
('SoundFX', 5, 20.00, 'Annoying FX Corporation');
INSERT INTO orders (product_id, quantity, price, buyer_info) VALUES
('X24 Bicycle', 1, 1500.00, 'Jennifer Juniper'),
('GreenStar Helmet', 1, 75.00, 'Donovan Liege'),
('GreenStar Helmet', 1, 75.00, 'Montgomery Python');
UDF๋ฅผ ๋ง๋ญ๋๋ค.
CREATE FUNCTION store_profit()
RETURNS NUMERIC(11, 2)
AS
$$
SELECT SUM( (o.price - i.price) * o.quantity)
FROM orders AS o, inventory AS i
WHERE o.product_id = i.product_id
$$
;
๋ค์๊ณผ ๊ฐ์ด ์ฟผ๋ฆฌ์์ UDF๋ฅผ ํธ์ถํ์ญ์์ค.
SELECT store_profit();
์ถ๋ ฅ:
SELECT store_profit();
+----------------+
| STORE_PROFIT() |
|----------------|
| 550.00 |
+----------------+
CREATE FUNCTION ํญ๋ชฉ์๋ ์ถ๊ฐ ์๊ฐ ํฌํจ๋์ด ์์ต๋๋ค.
๋ค์ํ ์ ์์ UDFs ์ฌ์ฉยถ
์ค์นผ๋ผ UDF๋ ์ค์นผ๋ผ ์์ ์ฌ์ฉํ ์ ์๋ ๋ชจ๋ ๊ณณ์์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์:
-- ----- These examples show a UDF called from different clauses ----- --
select MyFunc(column1) from table1;
select * from table1 where column2 > MyFunc(column1);
UDF์์ SQL ๋ณ์ ์ฌ์ฉยถ
์ด ์๋ SQL ๋ณ์๋ฅผ ์ค์ ํ๊ณ UDF ๋ด์์ ํด๋น ๋ณ์๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค.
SET id_threshold = (SELECT COUNT(*)/2 FROM table1);
CREATE OR REPLACE FUNCTION my_filter_function()
RETURNS TABLE (id int)
AS
$$
SELECT id FROM table1 WHERE id > $id_threshold
$$
;
๋ฉ๋ชจ์ด์ ์ด์ ๊ฐ๋ฅ ํจ์ยถ
์๋ ๋ค์์ ์ฐธ์กฐํ์ญ์์ค.
ํ ์ก์ธ์ค ์ ์ฑ ์์ ์ธ์๊ฐ ์๋ ๋ฉ๋ชจ์ด์ ์ด์ ๊ฐ๋ฅ ํจ์.
๋ง์คํน ์ ์ฑ ์ ์ธ์๋ก ๋ฉ๋ชจ์ด์ ์ด์ ๊ฐ๋ฅํ ํจ์.