Snowflake Scripting은 Snowflake SQL에 절차적 로직(procedural logic)을 추가하는 확장 기능이다.
사용 가능한 컨텍스트
DECLARE
-- (변수 선언, 커서 선언 등)
BEGIN
-- (Snowflake Scripting 및 SQL 구문)
EXCEPTION
-- (예외 처리 구문)
END;
| 섹션 | 필수 여부 | 역할 |
|---|---|---|
DECLARE | 선택 | 변수, 커서, RESULTSET, 예외 선언 |
BEGIN ... END | 필수 | SQL 및 Scripting 구문 실행 |
EXCEPTION | 선택 | 예외 처리 로직 |
DECLARE와EXCEPTION섹션은 선택 사항이다.BEGIN과END만으로도 블록 구성이 가능하다.
방법 1 - DECLARE 섹션에서 선언:
DECLARE
leg_a number(38, 2);
hypotenuse number(38, 5);
BEGIN
leg_a := 2;
...
END;
방법 2 - BEGIN 섹션에서 LET 키워드로 선언 및 할당:
BEGIN
let leg_b := 5;
...
END;
✅ 변수는 DECLARE 섹션 또는 BEGIN...END 섹션에서
LET을 사용해 선언 가능하다.
⚠️ 주의: 변수의 스코프는 선언된 블록 내부로 제한된다. 블록 외부에서는 사용 불가.
CREATE PROCEDURE pythagoras()
RETURNS float
LANGUAGE sql
AS
declare
leg_a number(38, 2);
hypotenuse number(38, 5);
begin
leg_a := 2;
let leg_b := 5;
hypotenuse := sqrt(square(leg_a) + square(leg_b));
return hypotenuse;
end;
⚠️ 중요 주의사항 :
SnowSQL 및 Classic Console에서는 Snowflake Scripting 블록을 올바르게 파싱하지 못한다.
이 경우 블록 전체를 달러 기호($$) 문자열 구분자로 감싸야 한다.
-- SnowSQL / Classic Console 사용 시
CREATE PROCEDURE pythagoras()
RETURNS float
LANGUAGE sql
AS
$$
declare
...
begin
...
end;
$$;
CALL pythagoras();
저장 프로시저나 UDF 외부에서 절차적 코드를 실행할 때 사용한다.
BEGIN 구문이 블록을 정의함과 동시에 실행한다 (별도의 CALL 명령 불필요).
-- 결과 컬럼 헤더는 'anonymous block'으로 표시됨
BEGIN
let count := 4;
if (count % 2 = 0) then
return 'even value';
else
return 'odd value';
end if;
end;
BEGIN
let count := 4;
if (count % 2 = 0) then
return 'even value';
else
return 'odd value';
end if;
end;
문법 포인트:
then 키워드 필요end if;로 종료else 절은 선택 사항✅ : IF / CASE 구문으로 조건부 흐름 제어 가능.
DECLARE
total integer default 0;
max_num integer default 10;
BEGIN
for i in 1 to max_num do
total := i + total;
end for;
return total;
END;
-- 결과: 55 (1+2+...+10)
문법 포인트:
for 변수 in 시작값 to 끝값 doend for;로 종료✅: FOR 외에도 WHILE, REPEAT, LOOP 반복 구문 지원.
쿼리 결과를 한 번에 한 행씩 순회할 때 사용한다.
DECLARE
total_amount float;
c1 cursor for select amount from transactions;
BEGIN
total_amount := 0.0;
for record in c1 do
total_amount := total_amount + record.amount;
end for;
return total_amount;
END;
-- 결과: 136.78
| 단계 | 명령 | 설명 |
|---|---|---|
| 1. 선언 | c1 CURSOR FOR SELECT ... | DECLARE 섹션 또는 BEGIN 섹션(LET) |
| 2. 열기 | OPEN c1; | 쿼리 실행 및 결과 로드 |
| 3. 읽기 | FETCH c1 INTO 변수; | 현재 행 읽기 후 포인터 이동 |
| 4. 닫기 | CLOSE c1; | 더 이상 필요 없을 때 닫기 |
✅ FOR 루프에서 커서를 사용할 경우
OPEN과CLOSE를 명시적으로 호출할 필요 없다.
DECLARE
res RESULTSET DEFAULT (select amount from transactions);
c1 CURSOR FOR res;
RESULTSET은 쿼리의 결과 집합을 가리키는 포인터(pointer) 역할을 하는 SQL 데이터 타입이다.
RESULTSET 자체로는 데이터에 직접 접근 불가. 아래 두 가지 방법 중 하나를 사용해야 한다:
1. TABLE(...) 구문으로 테이블 형태로 반환
2. 커서(cursor)로 순회
DECLARE
res resultset;
BEGIN
res := (select amount from transactions);
return table(res);
END;
-- 결과: amount 컬럼 테이블 반환 (101.01, 24.78, 10.99)
DECLARE
total_amount float;
res resultset default (select amount from transactions);
c1 cursor for res;
BEGIN
total_amount := 0.0;
for record in c1 do
total_amount := total_amount + record.amount;
end for;
return total_amount;
END;
-- 결과: 136.78
| 비교 항목 | Cursor | RESULTSET |
|---|---|---|
| 쿼리 실행 시점 | OPEN 명령 실행 시 | 쿼리가 할당(assign)되는 순간 |
| Bind parameter 지원 | ✅ (OPEN ... USING) | ❌ (직접 지원 안 함) |
| 테이블 반환 | RESULTSET_FROM_CURSOR() 경유 | TABLE(resultset) 직접 사용 |
| 주요 용도 | 행 단위 순회 처리 | 테이블 결과 반환 |
RESULTSET 직접 사용 불가SELECT * FROM my_result_set; 형태의 직접 쿼리 불가✅
TABLE(resultset_name)구문은 현재RETURN구문에서만 지원된다.
| 항목 | 핵심 내용 |
|---|---|
| Snowflake Scripting 용도 | SQL에 절차적 로직 추가 (Stored Procedure, UDF, Anonymous Block) |
| 블록 필수 섹션 | BEGIN ... END |
| 블록 선택 섹션 | DECLARE, EXCEPTION |
| 변수 선언 위치 | DECLARE 섹션 또는 BEGIN 섹션 (LET 키워드) |
| 변수 스코프 | 선언된 블록 내부로 제한 |
| SnowSQL/Classic Console 주의 | $$ 달러 기호로 블록 감싸야 함 |
| FOR 루프 커서 | OPEN / CLOSE 명시 불필요 |
| RESULTSET 접근 | TABLE() 또는 Cursor |
| RESULTSET 쿼리 실행 시점 | 쿼리 할당 즉시 |
| Cursor 쿼리 실행 시점 | OPEN 명령 실행 시 |