SnowConvert: Snowflake Scripting¶
BEGIN 및 COMMIT 트랜잭션¶
Applies to
[x] SQL 서버
[x] Azure 시냅스 분석
설명¶
Snowflake SQL, BEGIN 문을 실행하여 트랜잭션을 명시적으로 시작할 수 있습니다. Snowflake는 BEGIN WORK
와 BEGIN TRANSACTION
을 동의어로 지원합니다. Snowflake에서는 BEGIN TRANSACTION
을 사용할 것을 권장합니다.
트랜잭션은 COMMIT 을 실행하여 명시적으로 종료할 수 있습니다. 여기 에서 Snowflake 트랜잭션에 대해 자세히 알아보십시오.
샘플 소스 패턴 ¶
다음 예제에서는 BEGIN 및 COMMIT 트랜잭션 문에 대해 자세히 설명합니다.
Transact-SQL ¶
CREATE PROCEDURE TestTransaction
AS
BEGIN
DROP TABLE IF EXISTS NEWTABLE;
CREATE TABLE NEWTABLE(COL1 INT, COL2 VARCHAR);
BEGIN TRANSACTION;
INSERT INTO NEWTABLE VALUES (1, 'MICHAEL');
INSERT INTO NEWTABLE VALUES(2, 'JACKSON');
COMMIT TRANSACTION;
END
CREATE PROCEDURE TestTransaction
AS
BEGIN
DROP TABLE IF EXISTS NEWTABLE;
CREATE TABLE NEWTABLE(COL1 INT, COL2 VARCHAR);
BEGIN TRANSACTION LabelA;
INSERT INTO NEWTABLE VALUES (1, 'MICHAEL');
INSERT INTO NEWTABLE VALUES(2, 'JACKSON');
COMMIT TRANSACTION LabelA;
END
Snowflake SQL ¶
CREATE OR REPLACE PROCEDURE TestTransaction ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
DROP TABLE IF EXISTS NEWTABLE;
CREATE OR REPLACE TABLE NEWTABLE (
COL1 INT,
COL2 VARCHAR
);
BEGIN TRANSACTION;
INSERT INTO NEWTABLE VALUES (1, 'MICHAEL');
INSERT INTO NEWTABLE VALUES(2, 'JACKSON');
COMMIT;
END;
$$;
CREATE OR REPLACE PROCEDURE TestTransaction ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
DROP TABLE IF EXISTS NEWTABLE;
CREATE OR REPLACE TABLE NEWTABLE (
COL1 INT,
COL2 VARCHAR
);
BEGIN TRANSACTION
!!!RESOLVE EWI!!! /*** SSC-EWI-0101 - COMMENTED OUT TRANSACTION LABEL NAME BECAUSE IS NOT APPLICABLE IN SNOWFLAKE ***/!!!
LabelA;
INSERT INTO NEWTABLE VALUES (1, 'MICHAEL');
INSERT INTO NEWTABLE VALUES(2, 'JACKSON');
COMMIT;
END;
$$;
Known Issues¶
중첩된 트랜잭션은 Snowflake에서 지원되지 않습니다. 자세한 내용은 다음 설명서(https://docs.snowflake.com/en/sql-reference/transactions)를 참조하십시오.
CALL¶
Applies to
[x] SQL 서버
[x] Azure 시냅스 분석
설명 ¶
CALL 문은 ODBC API 문이 아닌 SQL 문의 일부이므로 이 문은 변환되지 않으므로 Snowflake 스크립팅에서 지원되지 않습니다.
CASE¶
Applies to
[x] SQL 서버
[x] Azure 시냅스 분석
참고
출력 코드의 일부 부분은 명확성을 위해 생략되었습니다.
설명¶
Transact-SQL 에는 식을 평가하고 조건부로 결과를 얻기 위한 두 가지 형식의 Case 식이 있습니다. 첫 번째는 input_expression 중 1개 이상의 when_expression과 일치하는지 평가하는 단순 대/소문자 식을 말합니다. 두 번째는 각 부Boolean_expression을 독립적으로 평가합니다. Else 절은 두 형식 모두에서 지원됩니다.
공식 Transact-SQL 사례 설명서에 따르면:
CASE 는 유효한 식을 허용하는 모든 문나 절에 사용할 수 있습니다. 예를 들어 SELECT, UPDATE, DELETE, SET 같은 문과 select_list, IN, WHERE, ORDER BY, HAVING 같은 절에 CASE 를 사용할 수 있습니다.
Transact-SQL 케이스에 대한 자세한 내용은 여기 를 확인하십시오.
-- Simple CASE expression:
CASE input_expression
WHEN when_expression THEN result_expression [ ...n ]
[ ELSE else_result_expression ]
END
-- Searched CASE expression:
CASE
WHEN boolean_expression THEN result_expression [ ...n ]
[ ELSE else_result_expression ]
END
참고: Transact-SQL 에서는 괄호 안에 입력_표현식과 부울_표현식을 선택적으로 캡슐화할 수 있으며, Snowflake Scripting도 마찬가지입니다.
샘플 소스 패턴 ¶
다음 예제에서는 Case 식을 사용할 수 있는 두 가지 시나리오와 Snowflake Scripting과의 차이점을 자세히 설명합니다.
대/소문자 사용 선택¶
Transact-SQL¶
CREATE OR ALTER PROCEDURE SelectCaseDemoProcedure
AS
SELECT TOP 10
LOGINID,
CASE (MARITALSTATUS)
WHEN 'S' THEN 'SINGLE'
WHEN 'M' THEN 'MARIED'
ELSE 'OTHER'
END AS status
FROM HUMANRESOURCES.EMPLOYEE;
GO
EXEC SelectCaseDemoProcedure;
CREATE OR ALTER PROCEDURE SelectCaseDemoProcedure
AS
SELECT TOP 10
LOGINID,
CASE
WHEN MARITALSTATUS = 'S' THEN 'SINGLE'
WHEN MARITALSTATUS = 'M' THEN 'MARIED'
ELSE 'OTHER'
END AS status
FROM HUMANRESOURCES.EMPLOYEE;
GO
EXEC SelectCaseDemoProcedure;
sqlLOGINID |status|
------------------------+------+
adventure-works\ken0 |SINGLE|
adventure-works\terri0 |SINGLE|
adventure-works\roberto0|MARIED|
adventure-works\rob0 |SINGLE|
adventure-works\gail0 |MARIED|
adventure-works\jossef0 |MARIED|
adventure-works\dylan0 |MARIED|
adventure-works\diane1 |SINGLE|
adventure-works\gigi0 |MARIED|
adventure-works\michael6|MARIED|
Snowflake Scripting <a href=”#expected-code”id=”expected-code”> ¶
이 시나리오에서는 Case 식 자체에 대한 차이점은 없습니다.
경고
res
변수를 선언하고 할당하는 것은 두 언어 간의 기능적 동등성을 입증하기 위한 것입니다. 실제 출력에는 표시되지 않습니다.
CREATE OR REPLACE PROCEDURE SelectCaseDemoProcedure ()
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
ProcedureResultSet RESULTSET;
BEGIN
ProcedureResultSet := (
SELECT TOP 10
LOGINID,
CASE (MARITALSTATUS)
WHEN 'S' THEN 'SINGLE'
WHEN 'M' THEN 'MARIED'
ELSE 'OTHER'
END AS status
FROM
HUMANRESOURCES.EMPLOYEE);
RETURN TABLE(ProcedureResultSet);
END;
$$;
CALL SelectCaseDemoProcedure();
CREATE OR REPLACE PROCEDURE SelectCaseDemoProcedure ()
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
ProcedureResultSet RESULTSET;
BEGIN
ProcedureResultSet := (
SELECT TOP 10
LOGINID,
CASE
WHEN MARITALSTATUS = 'S' THEN 'SINGLE'
WHEN MARITALSTATUS = 'M' THEN 'MARIED'
ELSE 'OTHER'
END AS status
FROM
HUMANRESOURCES.EMPLOYEE);
RETURN TABLE(ProcedureResultSet);
END;
$$;
CALL SelectCaseDemoProcedure();
LOGINID |STATUS|
-----------------------+------+
adventure-worksken0 |SINGLE|
adventure-works erri0 |SINGLE|
adventure-worksoberto0 |MARIED|
adventure-worksob0 |SINGLE|
adventure-worksgail0 |MARIED|
adventure-worksjossef0 |MARIED|
adventure-worksdylan0 |MARIED|
adventure-worksdiane1 |SINGLE|
adventure-worksgigi0 |MARIED|
adventure-worksmichael6|MARIED|
케이스를 사용하여 설정¶
AdventureWorks2019 데이터베이스는 두 언어 모두에서 동일한 결과를 얻기 위해 사용되었습니다.
Transact-SQL¶
CREATE OR ALTER PROCEDURE SetCaseDemoProcedure
AS
DECLARE @value INT;
DECLARE @result INT;
SET @value = 5;
SET @result =
CASE @value
WHEN 1 THEN @value * 10
WHEN 3 THEN @value * 20
WHEN 5 THEN @value * 30
WHEN 7 THEN @value * 40
ELSE -1
END;
RETURN @result
GO
DECLARE @result INT;
EXEC @result = SetCaseDemoProcedure;
PRINT @result;
CREATE OR ALTER PROCEDURE SetCaseDemoProcedure
AS
DECLARE @value INT;
DECLARE @result INT;
SET @value = 5;
SET @result =
CASE
WHEN @value = 1 THEN @value * 10
WHEN @value = 3 THEN @value * 20
WHEN @value = 5 THEN @value * 30
WHEN @value = 7 THEN @value * 40
ELSE -1
END;
RETURN @result
GO
DECLARE @result INT;
EXEC @result = SetCaseDemoProcedure;
PRINT @result;
|result|
|------|
|150 |
Snowflake Scripting <a href=”#expected-code”id=”expected-code”> ¶
경고
Snowflake Scripting에서는 변수에 대/소문자 식을 직접 설정할 수 없습니다. 두 Transact-SQL Case 식 형식은 Snowflake Scripting에서 다음 문법으로 변환됩니다.
CREATE OR REPLACE PROCEDURE SetCaseDemoProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
VALUE INT;
RESULT INT;
BEGIN
VALUE := 5;
CASE (:VALUE)
WHEN 1 THEN
RESULT := :VALUE * 10;
WHEN 3 THEN
RESULT := :VALUE * 20;
WHEN 5 THEN
RESULT := :VALUE * 30;
WHEN 7 THEN
RESULT := :VALUE * 40;
ELSE
RESULT := -1;
END;
RETURN :RESULT;
END;
$$;
DECLARE
RESULT INT;
BEGIN
CALL SetCaseDemoProcedure();
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'Print' NODE ***/!!!
PRINT @result;
END;
CREATE OR REPLACE PROCEDURE SetCaseDemoProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
VALUE INT;
RESULT INT;
BEGIN
VALUE := 5;
CASE
WHEN :VALUE = 1 THEN
RESULT := :VALUE * 10;
WHEN :VALUE = 3 THEN
RESULT := :VALUE * 20;
WHEN :VALUE = 5 THEN
RESULT := :VALUE * 30;
WHEN :VALUE = 7 THEN
RESULT := :VALUE * 40;
ELSE
RESULT := -1;
END;
RETURN :RESULT;
END;
$$;
DECLARE
RESULT INT;
BEGIN
CALL SetCaseDemoProcedure();
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'Print' NODE ***/!!!
PRINT @result;
END;
|result|
|------|
|150 |
Known Issues¶
문제가 발견되지 않았습니다.
관련 EWIs¶
SSC-EWI-0073: 보류 중 함수 동등성 검토.
CREATE PROCEDURE¶
Applies to
[x] SQL 서버
[x] Azure 시냅스 분석
참고
출력 코드의 일부 부분은 명확성을 위해 생략되었습니다.
설명¶
생성 프로시저 문을 사용하면 다음과 같은 저장 프로시저를 생성할 수 있습니다.
입력 매개 변수를 수락하고 여러 값을 출력 매개 변수의 형태로 호출 프로시저 또는 배치에 반환합니다.
다른 프로시저 호출을 포함하여 데이터베이스에서 작업을 수행하는 프로그래밍 문을 포함합니다.
호출 프로시저 또는 배치에 상태 값을 반환하여 성공 또는 실패(및 실패 이유)를 표시합니다.
Transact-SQL CREATE PROCEDURE 에 대한 자세한 내용은 여기 를 확인하십시오.
CREATE [ OR ALTER ] { PROC | PROCEDURE }
[schema_name.] procedure_name [ ; number ]
[ { @parameter [ type_schema_name. ] data_type }
[ VARYING ] [ = default ] [ OUT | OUTPUT | [READONLY]
] [ ,...n ]
[ WITH <procedure_option> [ ,...n ] ]
[ FOR REPLICATION ]
AS { [ BEGIN ] sql_statement [;] [ ...n ] [ END ] }
[;]
샘플 소스 패턴¶
본문이 없는 저장 프로시저¶
본문이 없는 저장 프로시저는 Transact-SQL 에서 허용되는 비정상적인 시나리오입니다. Snowflake Scripting에서는 본문이 없는 프로시저를 정의할 수 없지만 다음 예제에서는 동등성을 보여줍니다.
Transact-SQL¶
CREATE PROC SampleProcedure AS;
Snowflake Scripting¶
CREATE OR REPLACE PROCEDURE SampleProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
RETURN '';
END;
$$;
기본 저장 프로시저¶
다음 예제에서는 AdventureWorks2019 데이터베이스에 새 개인정보 보호 부서를 포함하는 간단한 저장 프로시저를 자세히 설명합니다.
Transact-SQL¶
CREATE OR ALTER PROCEDURE Add_Privacy_Department
AS
EXECUTE ('INSERT INTO HumanResources.Department VALUES (''Privacy'', ''Executive General and Administration'', default)');
Snowflake Scripting¶
CREATE OR REPLACE PROCEDURE Add_Privacy_Department ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE 'INSERT INTO HumanResources.Department VALUES ('Privacy', 'Executive General and Administration', default);';
END;
$$;
프로시저 변경¶
ALTER 프로시저에 대한 변환은 기본 프로시저와 동일합니다.
Transact-SQL¶
ALTER PROCEDURE procedureName
AS
SELECT 1 AS ThisDB;
Snowflake Scripting¶
CREATE OR REPLACE PROCEDURE procedureName ()
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
ProcedureResultSet RESULTSET;
BEGIN
ProcedureResultSet := (
SELECT 1 AS ThisDB);
RETURN TABLE(ProcedureResultSet);
END;
$$;
매개 변수 사용¶
매개 변수를 사용하여 논리를 구동하거나 저장 프로시저 내에서 동적 SQL 문을 구성할 수 있습니다. 다음 예제에서는 호출자가 보낸 인자에 따라 새 제품 가격을 설정하는 단순한 SetNewPrice 저장 프로시저를 구성합니다.
Transact-SQL¶
CREATE OR ALTER PROCEDURE SetNewPrice @ProductID INT, @NewPrice MONEY
AS
BEGIN
DECLARE @dynSqlStatement AS VARCHAR(300);
SET @dynSqlStatement = 'UPDATE Production.ProductListPriceHistory SET ListPrice = ' + CAST(@NewPrice AS VARCHAR(10)) + ' WHERE ProductID = ' + CAST(@ProductID AS VARCHAR(10)) + ' AND EndDate IS NULL';
EXECUTE (@dynSqlStatement);
END;
Snowflake Scripting¶
CREATE OR REPLACE PROCEDURE SetNewPrice (PRODUCTID INT, NEWPRICE NUMBER(38, 4))
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
DYNSQLSTATEMENT VARCHAR(300);
BEGIN
DYNSQLSTATEMENT := 'UPDATE Production.ProductListPriceHistory
SET
ListPrice = ' || CAST(:NEWPRICE AS VARCHAR(10)) || '
WHERE
ProductID = ' || CAST(:PRODUCTID AS VARCHAR(10)) || '
AND EndDate IS NULL;';
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE :DYNSQLSTATEMENT;
END;
$$;
출력 매개 변수¶
Transact- SQL출력 키워드는 매개 변수가 저장 프로시저 호출자에게 반환되는 값인 출력 변수임을 나타냅니다. 예를 들어, 다음 프로시저는 특정 직원의 휴가 시간을 반환합니다.
Transact-SQL¶
CREATE PROCEDURE GetVacationHours
@employeeId INT,
@vacationHours INT OUTPUT
AS
BEGIN
SELECT @vacationHours = VacationHours
FROM HumanResources.Employee
WHERE NationalIDNumber = @employeeID
END;
Snowflake Scripting¶
CREATE OR REPLACE PROCEDURE GetVacationHours (EMPLOYEEID INT, VACATIONHOURS INT)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
SELECT
VacationHours
INTO
:VACATIONHOURS
FROM
HumanResources.Employee
WHERE
NationalIDNumber = :EMPLOYEEID;
RETURN VACATIONHOURS;
END;
$$;
경고
Snowflake 스크립팅 저장 프로시저에서는 1개의 출력 매개 변수만 반환할 수 있습니다.
선택적 매개 변수¶
매개 변수를 선언할 때 기본값이 지정되어 있는 경우 매개 변수는 선택 사항으로 간주됩니다. 프로시저 호출에서 선택적 매개 변수에 대한 값을 제공할 필요는 없습니다.
Transact-SQL¶
CREATE PROCEDURE OPTIONAL_PARAMETER @VAR1 INT = 1, @VAR2 INT = 2
AS
BEGIN
RETURN NULL;
END
GO
EXEC OPTIONAL_PARAMETER @VAR2 = 4
Snowflake Scripting¶
CREATE OR REPLACE PROCEDURE OPTIONAL_PARAMETER (VAR1 INT DEFAULT 1, VAR2 INT DEFAULT 2)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
RETURN NULL;
END;
$$;
CALL OPTIONAL_PARAMETER(VAR2 => 4);
EXECUTE AS¶
Transact-SQL 의 EXECUTE AS 절은 저장 프로시저의 실행 컨텍스트를 정의하여 데이터베이스 엔진이 프로시저 내에서 참조되는 오브젝트에 대한 권한을 검증하는 데 사용하는 사용자 계정을 지정합니다. 예를 들어, 이전 GetVacationHours 프로시저를 수정하여 다른 실행 컨텍스트를 정의할 수 있습니다.
소유자(Snowflake Scripting의 기본값)
Transact-SQL¶
CREATE OR ALTER PROCEDURE GetVacationHours
@employeeId INT,
@vacationHours INT OUTPUT
WITH EXECUTE AS OWNER
AS
BEGIN
SELECT @vacationHours = VacationHours
FROM HumanResources.Employee
WHERE NationalIDNumber = @employeeID
END;
Snowflake Scripting¶
CREATE OR REPLACE PROCEDURE GetVacationHours (EMPLOYEEID INT, VACATIONHOURS INT)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS OWNER
AS
$$
BEGIN
SELECT
VacationHours
INTO
:VACATIONHOURS
FROM
HumanResources.Employee
WHERE
NationalIDNumber = :EMPLOYEEID;
RETURN VACATIONHOURS;
END;
$$;
호출자
Transact-SQL¶
CREATE OR ALTER PROCEDURE GetVacationHours
@employeeId INT,
@vacationHours INT OUTPUT
WITH EXECUTE AS CALLER
AS
BEGIN
SELECT @vacationHours = VacationHours
FROM HumanResources.Employee
WHERE NationalIDNumber = @employeeID
END;
Snowflake Scripting¶
CREATE OR REPLACE PROCEDURE GetVacationHours (EMPLOYEEID INT, VACATIONHOURS INT)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
SELECT
VacationHours
INTO
:VACATIONHOURS
FROM
HumanResources.Employee
WHERE
NationalIDNumber = :EMPLOYEEID;
RETURN VACATIONHOURS;
END;
$$;
경고
SELF 및 특정 사용자(‘user_name’) 실행 컨텍스트는 Snowflake Scripting에서 지원되지 않습니다.
READONLY AND VARYING PARAMETERS¶
Snowflake는 READONLY
및 VARYING
매개 변수 유형을 지원하지 않으며 대신 FDM 이 추가됩니다.
Transact-SQL¶
CREATE OR ALTER PROCEDURE GetVacationHours
@Param1 INT READONLY,
@Param2 INT VARYING
AS
BEGIN
SELECT * FROM Table1;
END;
Snowflake Scripting¶
CREATE OR REPLACE PROCEDURE GetVacationHours (PARAM1 INT !!!RESOLVE EWI!!! /*** SSC-EWI-0058 - FUNCTIONALITY FOR 'READONLY PARAMETERS' IS NOT CURRENTLY SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!, PARAM2 INT !!!RESOLVE EWI!!! /*** SSC-EWI-0058 - FUNCTIONALITY FOR 'VARYING PARAMETERS' IS NOT CURRENTLY SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!)
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
ProcedureResultSet RESULTSET;
BEGIN
ProcedureResultSet := (
SELECT
*
FROM
Table1);
RETURN TABLE(ProcedureResultSet);
END;
$$;
Known Issues¶
지원되지 않는 선택적 인자¶
[VARYING] cursor 매개 변수에만 적용됩니다. 출력 매개 변수로 지원되는 결과 세트를 지정합니다. 이 매개 변수는 프로시저에 의해 동적으로 구성되며 그 내용은 다를 수 있습니다. Snowflake Scripting은 CURSOR 를 유효한 반환 데이터 타입으로 지원하지 않습니다.
[= default] 기본값 정의를 통해 매개 변수를 선택 사항으로 설정합니다. Snowflake Scripting은 기본적으로 기본값 매개 변수를 지원하지 않습니다.
[READONLY] 프로시저 본문 내에서 매개 변수를 업데이트하거나 수정할 수 없음을 나타냅니다. 현재 Snowflake Scripting에서는 지원되지 않습니다.
[WITH RECOMPILE] 데이터베이스 엔진이 저장 프로시저가 실행될 때마다 쿼리 계획을 컴파일하도록 강제합니다. 현재 Snowflake Scripting에서는 지원되지 않습니다.
[WITH ENCRYPTION] 저장 프로시저의 텍스트를 암호화하는 데 사용됩니다. 시스템 테이블 또는 데이터베이스 파일에 대한 액세스 권한이 있는 사용자(예: sysadmin 사용자)만 프로시저가 생성된 후 프로시저 텍스트에 액세스할 수 있습니다. 현재 Snowflake Scripting에서는 지원되지 않습니다.
[FOR REPLICATION] 저장 프로시저가 복제 중에만 실행되도록 제한합니다. 현재 Snowflake Scripting에서는 지원되지 않습니다.
관련 EWIS¶
SSC-EWI-0030: 아래 문에는 동적 SQL 의 사용법이 있습니다.
SSC-EWI-0058: 기능은 현재 Snowflake Scripting에서 지원되지 않습니다.
CURSOR¶
Applies to
[x] SQL 서버
[x] Azure 시냅스 분석
참고
출력 코드의 일부 부분은 명확성을 위해 생략되었습니다.
설명¶
Transact-SQL 문은 완전한 결과 세트를 생성하지만 한 번에 한 행씩 처리하는 것이 가장 좋은 경우가 있습니다. 결과 세트에 커서를 올리면 결과 세트를 한 번에 한 행씩 처리할 수 있습니다. cursor 데이터 타입을 사용하여 변수 또는 매개 변수에 커서를 할당할 수 있습니다. 자세한 내용은 여기 에서 확인할 수 있습니다.
//ISO Syntax
DECLARE cursor_name [ INSENSITIVE ] [ SCROLL ] CURSOR
FOR select_statement
[ FOR { READ ONLY | UPDATE [ OF column_name [ ,...n ] ] } ]
[;]
//Transact-SQL Extended Syntax
DECLARE cursor_name CURSOR [ LOCAL | GLOBAL ]
[ FORWARD_ONLY | SCROLL ]
[ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]
[ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ]
[ TYPE_WARNING ]
FOR select_statement
[ FOR UPDATE [ OF column_name [ ,...n ] ] ]
[;]
FETCH
[ [ NEXT | PRIOR | FIRST | LAST
| ABSOLUTE { n | @nvar }
| RELATIVE { n | @nvar }
]
FROM
]
{ { [ GLOBAL ] cursor_name } | @cursor_variable_name }
[ INTO @variable_name [ ,...n ] ]
OPEN { { [ GLOBAL ] cursor_name } | cursor_variable_name }
CLOSE { { [ GLOBAL ] cursor_name } | cursor_variable_name }
DEALLOCATE { { [ GLOBAL ] cursor_name } | @cursor_variable_name }
샘플 소스 패턴¶
Transact-SQL¶
다음 매개 변수는 Snowflake Scripting에서 본질적으로 지원된다는 점에 유의하십시오.
[LOCAL].
[FORWARD_ONLY].
[FAST_FORWARD]는 FORWARD_ONLY (FETCH NEXT 전용) 및 READ_ONLY 를 지정합니다.
[READ_ONLY] WHERE CURRENT OF 는 Snowflake Scripting에 존재하지 않습니다.
CREATE TABLE vEmployee (
PersonID INT,
LastName VARCHAR(255),
FirstName VARCHAR(255),
);
INSERT INTO vEmployee(PersonID, LastName, FirstName)
VALUES
(1, 'AA', 'A'),
(2, 'BB', 'B'),
(3, 'CC', 'C'),
(4, 'DD', 'D'),
(5, 'EE', 'E'),
(6, 'FF', 'F'),
(7, 'GG', 'G');
CREATE OR ALTER PROCEDURE CursorExample
AS
DECLARE
@CursorVar CURSOR,
@firstName VARCHAR;
SET @CursorVar = CURSOR LOCAL FORWARD_ONLY STATIC READ_ONLY
FOR
SELECT FirstName
FROM vEmployee;
OPEN @CursorVar;
FETCH NEXT FROM @CursorVar INTO @firstName;
FETCH NEXT FROM @CursorVar INTO @firstName;
CLOSE @CursorVar;
SELECT @firstName;
GO
B
Snowflake Scripting¶
CREATE OR REPLACE TABLE vEmployee (
PersonID INT,
LastName VARCHAR(255),
FirstName VARCHAR(255)
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
;
INSERT INTO vEmployee (PersonID, LastName, FirstName)
VALUES
(1, 'AA', 'A'),
(2, 'BB', 'B'),
(3, 'CC', 'C'),
(4, 'DD', 'D'),
(5, 'EE', 'E'),
(6, 'FF', 'F'),
(7, 'GG', 'G');
CREATE OR REPLACE PROCEDURE CursorExample ()
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
CURSORVAR CURSOR
FOR
SELECT FirstName
FROM vEmployee;
FIRSTNAME VARCHAR;
ProcedureResultSet RESULTSET;
BEGIN
OPEN CURSORVAR;
FETCH
CURSORVAR
INTO
:FIRSTNAME;
FETCH
CURSORVAR
INTO
:FIRSTNAME;
CLOSE CURSORVAR;
ProcedureResultSet := (
SELECT
:FIRSTNAME);
RETURN TABLE(ProcedureResultSet);
END;
$$;
B
Known Issues¶
다음 매개 변수는 지원되지 않습니다.
DECLARE CURSOR
[ GLOBAL ] 연결에 의해 실행되는 저장 프로시저 또는 배치에서 커서 이름을 참조할 수 있습니다. Snowflake Scripting은 커서를 로컬로만 사용할 수 있습니다.
[ SCROLL ] Snowflake Scripting는 FETCH NEXT 만 지원합니다.
[ KEYSET | DYNAMIC ] 커서를 열고 테이블에 대한 업데이트가 수행된 후 커서를 가져올 때 일부 변경 사항이 표시될 수 있으며, Snowflake Scripting은 STATIC 만 지원합니다. 즉, 커서가 열린 후에는 테이블의 변경 사항이 커서에 의해 감지되지 않습니다.
[SCROLL_LOCKS] 커서를 통해 수행된 위치 업데이트 또는 삭제가 성공하도록 보장하도록 지정하며, Snowflake Scripting은 이를 보장할 수 없습니다.
[OPTIMISTIC] 커서를 통해 업데이트 또는 삭제가 수행되면 타임스탬프 열 값을 비교하거나 테이블에 타임스탬프 열이 없는 경우 체크섬 값을 사용하여 행이 커서로 읽혀진 후 수정되었는지 여부를 확인합니다. Snowflake Scripting에는 이를 복제하는 내부 프로세스가 없습니다.
[TYPE_WARNING]
FETCH
[PRIOR | FIRST | LAST] Snowscripting은 NEXT 만 지원합니다.
[ABSOLUTE] Snowflake Scripting은 NEXT 만 지원하지만, 동작은 복제할 수 있습니다.
[RELATIVE] Snowflake Scripting이지만, 동작은 복제할 수 있습니다.
[ GLOBAL ] 연결에 의해 실행되는 저장 프로시저 또는 배치에서 커서 이름을 참조할 수 있습니다. Snowflake Scripting은 커서를 로컬로만 사용할 수 있습니다.
FETCH 가 없는 INTO 는 지원되지 않습니다.
FETCH 문이 루프 내부에 위치하는 경우 Snowflake 변환 코드 성능에 영향을 미칠 수 있으므로 복잡한 패턴으로 간주됩니다. 자세한 내용은 관련 문제 섹션을 확인하십시오.
내부 루프 샘플 가져오기¶
CREATE OR ALTER PROCEDURE cursor_procedure1
AS
BEGIN
DECLARE cursor1 CURSOR FOR SELECT col1 FROM my_table;
WHILE 1=0
BEGIN
FETCH NEXT FROM @cursor1 INTO @variable1;
END
END;
CREATE OR REPLACE PROCEDURE cursor_procedure1 ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
--** SSC-FDM-TS0013 - SNOWFLAKE SCRIPTING CURSOR ROWS ARE NOT MODIFIABLE **
cursor1 CURSOR
FOR
SELECT
col1
FROM
my_table;
BEGIN
WHILE (1=0) LOOP
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
FETCH
CURSOR1
INTO
:VARIABLE1;
END LOOP;
END;
$$;
OPEN
[ GLOBAL ] 연결에 의해 실행되는 저장 프로시저 또는 배치에서 커서 이름을 참조할 수 있습니다. Snowflake Scripting은 커서를 로컬로만 사용할 수 있습니다.
CLOSE
[ GLOBAL ] 연결에 의해 실행되는 저장 프로시저 또는 배치에서 커서 이름을 참조할 수 있습니다. Snowflake Scripting은 커서를 로컬로만 사용할 수 있습니다.
DEALLOCATED 커서 참조를 제거하며 Snowflake Scripting에는 이에 상응하는 기능은 없습니다.
WHERE CURRENT OF 이 문의 사용은 지원되지 않습니다. 예:
CREATE OR ALTER PROCEDURE CursorWithCurrent
AS
DECLARE
@CursorVar CURSOR;
SET @CursorVar = CURSOR
FOR
SELECT FirstName
FROM vEmployee;
OPEN @CursorVar;
FETCH NEXT FROM @CursorVar;
FETCH NEXT FROM @CursorVar;
UPDATE vEmployee SET LastName = 'Changed' WHERE CURRENT OF @CursorVar;
CLOSE @CursorVar;
GO
환경 변수
@@CURSOR_ROWS
@@FETCH_STATUS
관련 EWIs¶
SSC-FDM-TS0013: Snowflake Scripting 커서 행은 수정할 수 없습니다.
SSC-PRF-0003: 루프 내부의 Fetch는 복잡한 패턴으로 간주되며, 이로 인해 Snowflake 성능이 저하될 수 있습니다.
DECLARE¶
Applies to
[x] SQL 서버
[x] Azure 시냅스 분석
설명¶
Transact-SQL DECLARE 문을 사용하면 배치 또는 저장 프로시저의 범위에서 사용할 수 있는 변수를 만들 수 있습니다. Transact-SQL DECLARE 에 대한 자세한 내용은 여기 를 확인하십시오.
-- Syntax for SQL Server and Azure SQL Database
DECLARE
{
{ @local_variable [AS] data_type [ = value ] }
| { @cursor_variable_name CURSOR }
} [,...n]
| { @table_variable_name [AS] <table_type_definition> }
<table_type_definition> ::=
TABLE ( { <column_definition> | <table_constraint> } [ ,...n] )
<column_definition> ::=
column_name { scalar_data_type | AS computed_column_expression }
[ COLLATE collation_name ]
[ [ DEFAULT constant_expression ] | IDENTITY [ (seed ,increment ) ] ]
[ ROWGUIDCOL ]
[ <column_constraint> ]
<column_constraint> ::=
{ [ NULL | NOT NULL ]
| [ PRIMARY KEY | UNIQUE ]
| CHECK ( logical_expression )
| WITH ( <index_option > )
}
<table_constraint> ::=
{ { PRIMARY KEY | UNIQUE } ( column_name [ ,...n] )
| CHECK ( search_condition )
}
샘플 소스 패턴¶
변수 선언하기¶
변수는 다양한 방법으로 생성할 수 있습니다. 변수는 기본값이 있을 수도 있고 없을 수도 있으며 여러 변수를 같은 라인에 선언할 수 있습니다.
Snowflake Scripting에서는 한 라인에 2개 이상의 변수를 생성할 수 없습니다.
Transact-SQL¶
DECLARE @find VARCHAR(30);
DECLARE @find2 VARCHAR(30) = 'Default';
DECLARE @var VARCHAR(5), @var2 varchar(5);
Snowflake Scripting
DECLARE
FIND VARCHAR(30);
FIND2 VARCHAR(30) := 'Default';
VAR VARCHAR(5);
VAR2 VARCHAR(5);
BEGIN
RETURN '';
END;
테이블 변수 선언하기¶
Transact-SQL 을 사용하면 일반 테이블로 사용할 수 있는 테이블 변수를 만들 수 있습니다. Snowflake Scripting은 이를 지원하지 않으며 대신 테이블을 생성한 다음 프로시저가 끝날 때 드롭할 수 있습니다.
Transact-SQL¶
DECLARE @MyTableVar TABLE(
column1 varchar(10));
Snowflake Scripting
BEGIN
DECLARE
T_MYTABLEVAR TABLE(
column1 VARCHAR(10));
END;
루틴 외부의 DECLARE 문(함수 및 프로시저)¶
Transact-SQL 과 달리, Snowflake는 함수나 프로시저와 같은 루틴 외부에서 DECLARE 같은 고립된 문을 실행하는 것을 지원하지 않습니다. 이 시나리오의 경우 다음 예시와 같이 문을 익명 블록으로 캡슐화해야 합니다. 이 문은 일반적으로 SET STATEMENT
앞에 사용됩니다.
Transact-SQL¶
DECLARE @Group nvarchar(50), @Sales MONEY;
SET @Group = N'North America';
SET @Sales = 2000000;
Snowflake Scripting
DECLARE
_GROUP VARCHAR(50);
SALES NUMBER(38, 4);
BEGIN
_GROUP := 'North America';
SALES := 2000000;
END;
DECLARE 문으로만 구성된 시나리오가 있는 경우 이 블록은 비어 있을 수 없으므로 오류를 방지하기 위해 BEGIN…END 블록에 RETURN NULL 문을 포함해야 합니다.
Transact-SQL¶
DECLARE @Group nvarchar(50), @Sales MONEY;
Snowflake Scripting
DECLARE
_GROUP VARCHAR(50);
SALES NUMBER(38, 4);
BEGIN
RETURN '';
END;
Known Issues¶
문제가 발견되지 않았습니다.
관련 EWIs¶
관련 EWIs 없음.
EXECUTE¶
Applies to
[x] SQL 서버
[x] Azure 시냅스 분석
참고
출력 코드의 일부 부분은 명확성을 위해 생략되었습니다.
설명¶
Transact- SQLEXECUTE문을 사용하면 Transact- SQL배치, 스칼라 값 사용자 정의 함수 또는 저장 프로시저 내에서 명령 문자열 또는 문 문자열을 실행할 수 있습니다. Transact-SQL EXECUTE 에 대한 자세한 내용은 여기 를 확인하십시오.
-- Execute a character string
{ EXEC | EXECUTE }
( { @string_variable | [ N ]'tsql_string' } [ + ...n ] )
[ AS { LOGIN | USER } = ' name ' ]
[;]
-- Execute a stored procedure or function
[ { EXEC | EXECUTE } ]
{
[ @return_status = ]
{ module_name [ ;number ] | @module_name_var }
[ [ @parameter = ] { value
| @variable [ OUTPUT ]
| [ DEFAULT ]
}
]
[ ,...n ]
[ WITH <execute_option> [ ,...n ] ]
}
[;]
샘플 소스 패턴¶
문자 문자열 실행¶
EXECUTE 는 리터럴로 직접 전달된 SQL 작업을 수행하는 데 사용할 수 있습니다. 다음 예제에서는 AdventureWorks2019 데이터베이스에 새 개인정보 보호 부서를 삽입하는 저장 프로시저 내에서 사용됩니다.
Transact-SQL¶
CREATE OR ALTER PROCEDURE AddPrivacyDepartment
AS
EXECUTE ('INSERT INTO HumanResources.Department VALUES (''Privacy'', ''Executive General and Administration'', default)');
Snowflake Scripting¶
CREATE OR REPLACE PROCEDURE AddPrivacyDepartment ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE 'INSERT INTO HumanResources.Department VALUES ('Privacy', 'Executive General and Administration', default);';
END;
$$;
저장 프로시저 실행¶
EXECUTE 를 사용하여 기존 저장 프로시저를 호출할 수도 있습니다. 다음 예제는 위에서 생성한 AddPrivacyDepartment 프로시저를 호출합니다. 그런 다음 SELECT 를 실행하여 새 부서가 성공적으로 포함되었는지 확인합니다.
Transact-SQL¶
EXECUTE AddPrivacyDepartment;
SELECT DepartmentID, Name, GroupName FROM HumanResources.Department;
DepartmentID|Name |GroupName |ModifiedDate |
------------+--------------------------+------------------------------------+-----------------------+
1|Engineering |Research and Development |2008-04-30 00:00:00.000|
2|Tool Design |Research and Development |2008-04-30 00:00:00.000|
3|Sales |Sales and Marketing |2008-04-30 00:00:00.000|
4|Marketing |Sales and Marketing |2008-04-30 00:00:00.000|
5|Purchasing |Inventory Management |2008-04-30 00:00:00.000|
6|Research and Development |Research and Development |2008-04-30 00:00:00.000|
7|Production |Manufacturing |2008-04-30 00:00:00.000|
8|Production Control |Manufacturing |2008-04-30 00:00:00.000|
9|Human Resources |Executive General and Administration|2008-04-30 00:00:00.000|
10|Finance |Executive General and Administration|2008-04-30 00:00:00.000|
11|Information Services |Executive General and Administration|2008-04-30 00:00:00.000|
12|Document Control |Quality Assurance |2008-04-30 00:00:00.000|
13|Quality Assurance |Quality Assurance |2008-04-30 00:00:00.000|
14|Facilities and Maintenance|Executive General and Administration|2008-04-30 00:00:00.000|
15|Shipping and Receiving |Inventory Management |2008-04-30 00:00:00.000|
16|Executive |Executive General and Administration|2008-04-30 00:00:00.000|
17|Privacy |Executive General and Administration|2021-11-17 12:42:54.640|
Snowflake Scripting¶
CALL AddPrivacyDepartment();
SELECT
DepartmentID,
Name,
GroupName
FROM
HumanResources.Department;
DEPARTMENTID|NAME |GROUPNAME |MODIFIEDDATE |
------------+--------------------------+------------------------------------+-----------------------+
1|Engineering |Research and Development |2021-11-17 10:29:36.963|
2|Tool Design |Research and Development |2021-11-17 10:29:37.463|
3|Sales |Sales and Marketing |2021-11-17 10:29:38.192|
4|Marketing |Sales and Marketing |2021-11-17 10:29:38.733|
5|Purchasing |Inventory Management |2021-11-17 10:29:39.298|
6|Research and Development |Research and Development |2021-11-17 10:31:53.770|
7|Production |Manufacturing |2021-11-17 10:31:55.082|
8|Production Control |Manufacturing |2021-11-17 10:31:56.638|
9|Human Resources |Executive General and Administration|2021-11-17 10:31:57.507|
10|Finance |Executive General and Administration|2021-11-17 10:31:58.473|
11|Information Services |Executive General and Administration|2021-11-17 10:34:35.200|
12|Document Control |Quality Assurance |2021-11-17 10:34:35.741|
13|Quality Assurance |Quality Assurance |2021-11-17 10:34:36.277|
14|Facilities and Maintenance|Executive General and Administration|2021-11-17 10:34:36.832|
15|Shipping and Receiving |Inventory Management |2021-11-17 10:34:37.373|
16|Executive |Executive General and Administration|2021-11-17 10:34:37.918|
17|Privacy |Executive General and Administration|2021-11-17 10:46:43.345|
로컬 변수 실행 및 매개 변수 사용¶
EXECUTE 문의 일반적인 사용 사례는 동적 SQL 문이 필요한 경우입니다. 이 경우 문자열 리터럴을 실행하는 대신 문을 동적으로 구성하고 로컬 변수에 할당하여 실행할 수 있습니다. 호출된 저장 프로시저에 인자 세트를 전송하여 동적 SQL 명령을 구성할 수 있습니다.
다음 예제에서는 EXECUTE 문을 사용하여 호출자가 보낸 인자에 따라 새 제품 가격을 설정하는 간단한 SetNewPrice 저장 프로시저를 구성합니다. 마지막으로 SELECT 를 통해 새 제품 가격을 확인합니다.
Transact-SQL¶
CREATE OR ALTER PROCEDURE SetNewPrice @ProductID INT, @NewPrice MONEY
AS
DECLARE @dynSqlStatement AS VARCHAR(300);
SET @dynSqlStatement = 'UPDATE Production.ProductListPriceHistory SET ListPrice = ' + CAST(@NewPrice AS VARCHAR(10)) + ' WHERE ProductID = ' + CAST(@ProductID AS VARCHAR(10)) + ' AND EndDate IS NULL';
EXECUTE (@dynSqlStatement);
GO
EXECUTE Set_New_Price @ProductID = 707, @NewPrice = 34.99;
SELECT ListPrice FROM Production.ProductListPriceHistory WHERE ProductID = 707 AND EndDate IS NULL;
ListPrice|
---------+
34.9900|
Snowflake Scripting¶
CREATE OR REPLACE PROCEDURE SetNewPrice (PRODUCTID INT, NEWPRICE NUMBER(38, 4))
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
DYNSQLSTATEMENT VARCHAR(300);
BEGIN
DYNSQLSTATEMENT := 'UPDATE Production.ProductListPriceHistory
SET
ListPrice = ' || CAST(:NEWPRICE AS VARCHAR(10)) || '
WHERE
ProductID = ' || CAST(:PRODUCTID AS VARCHAR(10)) || '
AND EndDate IS NULL;';
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE :DYNSQLSTATEMENT;
END;
$$;
CALL Set_New_Price(707, 34.99);
SELECT
ListPrice
FROM
Production.ProductListPriceHistory
WHERE
ProductID = 707 AND EndDate IS NULL;
LISTPRICE|
---------+
34.9900|
Known Issues¶
반환 코드 사용¶
Transact-SQL EXECUTE 구문에는 스칼라 값 사용자 정의 함수의 반환 상태를 저장하는 스칼라 변수를 생성할 수 있는 @return_status 선택적 인자가 포함되어 있습니다.
반환 상태는 정수 데이터 타입으로 제한되지만 저장 프로시저에서도 사용할 수 있습니다.
이 기능을 표현하기 위해 위의 예제를 약간 수정하여 새 제품 가격을 과거 가격의 평균으로 계산하는 사용자 정의 함수를 만들 수 있습니다. 이제 저장 프로시저에 전달하는 대신 CalculateAveragePrice 함수를 호출하여 새 가격을 구하고 반환 변수에 저장하여 동적 SQL 을 구성할 수 있습니다.
Transact-SQL¶
CREATE OR ALTER FUNCTION CalculateAveragePrice(@pid INT)
RETURNS MONEY
AS
BEGIN
DECLARE @average AS MONEY;
SELECT @average = AVG(LISTPRICE) FROM Production.ProductListPriceHistory WHERE ProductID = @pid;
RETURN @average;
END;
GO
CREATE OR ALTER PROCEDURE SetNewPrice @ProductID INT
AS
DECLARE @averageHistoricalPrice MONEY;
EXECUTE @averageHistoricalPrice = [dbo].Calculate_Average_Price @pid=@ProductID;
UPDATE Production.ProductListPriceHistory SET ListPrice = @averageHistoricalPrice WHERE ProductID = @ProductID AND EndDate IS NULL;
GO
EXECUTE Set_New_Price @ProductID = 707;
SELECT ListPrice FROM Production.ProductListPriceHistory WHERE ProductID = 707 AND EndDate IS NULL;
ListPrice|
---------+
34.0928|
Snowflake Scripting¶
CREATE OR REPLACE FUNCTION CalculateAveragePrice (PID INT)
RETURNS NUMBER(38, 4)
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
AS
$$
WITH CTE1 AS
(
SELECT
AVG(LISTPRICE) AS AVERAGE FROM
Production.ProductListPriceHistory
WHERE
ProductID = PID
)
SELECT
AVERAGE
FROM
CTE1
$$;
CREATE OR REPLACE PROCEDURE SetNewPrice (PRODUCTID INT)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
AVERAGEHISTORICALPRICE NUMBER(38, 4);
BEGIN
CALL dbo.Calculate_Average_Price(:PRODUCTID);
UPDATE Production.ProductListPriceHistory
SET
ListPrice = :AVERAGEHISTORICALPRICE
WHERE
ProductID = :PRODUCTID
AND EndDate IS NULL;
END;
$$;
CALL Set_New_Price(707);
SELECT
ListPrice
FROM
Production.ProductListPriceHistory
WHERE
ProductID = 707 AND EndDate IS NULL;
지원되지 않는 선택적 인자¶
@return_status
;number
@module__name_v_ar
WITH RECOMPILE, WITH RESULT SETS NONE, WITH <결과 세트 정의>
관련 EWIs¶
SSC-EWI-0030: 아래 문에는 동적 SQL 의 사용법이 있습니다.
IF¶
Applies to
[x] SQL 서버
[x] Azure 시냅스 분석
설명 ¶
IF 절은 부울 식이 true이면 SQL 문 또는 문 블록을 조건부로 실행하고, 그렇지 않으면 선택 사항인 ELSE 절의 문이 실행되도록 합니다. Transact-SQL 은 또한 여러 조건이 필요한 경우 여러 개의 IF… ELSE 절을 포함하거나 CASE 절을 사용할 수 있도록 지원합니다.
Transact-SQL IF…ELSE 에 대한 자세한 내용은 여기 를 확인하십시오.
IF Boolean_expression
{ sql_statement | statement_block }
[ ELSE
{ sql_statement | statement_block } ]
참고: 문 블록을 정의하려면 플로우 제어 키워드 BEGIN
및 END
를 사용합니다.
샘플 소스 패턴 ¶
Transact-SQL¶
다음 코드는 Transact-SQL 의 IF… ELSE 에서 @값이 5 미만인지, 5에서 10 사이인지 또는 다른 값을 갖는지 식별하기 위해 변수를 조건부로 지정합니다. 값은 7로 초기화되므로 두 번째 조건은 true이어야 하고 결과는 200이어야 합니다.
CREATE OR ALTER PROCEDURE IfElseDemoProcedure
AS
DECLARE @value INT;
SET @value = 7;
IF @value < 5
SET @value = 100;
ELSE IF @value >= 5 AND @value < 10
BEGIN
SET @value = 300;
SET @value = @value - 100;
END;
ELSE
SET @value = -1;
RETURN @value
GO
DECLARE @result INT;
EXEC @result = IfElseDemoProcedure;
PRINT @result;
|result|
|------|
|200 |
Snowflake Scripting <a href=”#expected-code”id=”expected-code”> ¶
참고
Snowflake Scripting에서 임베드된 IF…ELSE 조건은 ELSEIF 이라고 합니다.
또한 부울 조건은 괄호 안에 괄호로 묶여 있으며 절은 항상 END IF 식으로 끝납니다.
또한 Snowflake Scripting에서는 BEGIN 및 END 키워드를 사용하여 문 블록을 정의할 필요는 없지만 필요한 경우 이 키워드를 사용할 수 있습니다.
CREATE OR REPLACE PROCEDURE IfElseDemoProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
VALUE INT;
BEGIN
VALUE := 7;
IF (:VALUE < 5) THEN
VALUE := 100;
ELSEIF (:VALUE >= 5 AND :VALUE < 10) THEN
BEGIN
VALUE := 300;
VALUE := :VALUE - 100;
END;
ELSE
VALUE := -1;
END IF;
RETURN :VALUE;
END;
$$;
DECLARE
RESULT INT;
BEGIN
CALL IfElseDemoProcedure();
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'Print' NODE ***/!!!
PRINT @result;
END;
|result|
|------|
|200 |
루틴 외부의 IF 문(함수 및 프로시저)¶
Transact-SQL 과 달리 Snowflake는 함수나 프로시저와 같은 루틴 외부에서 IF…ELSE 같은 고립된 문을 실행하는 것을 지원하지 않습니다. 이 시나리오의 경우 다음 예시와 같이 문을 익명 블록으로 캡슐화해야 합니다. 출력 값을 올바르게 반환하는 방법에 대한 자세한 내용은 SELECT 섹션에서 확인할 수 있습니다.
Transact-SQL¶
DECLARE @maxWeight FLOAT, @productKey INTEGER
SET @maxWeight = 100.00
SET @productKey = 424
IF @maxWeight <= 99
SELECT @productKey, 'This product is too heavy to ship and is only available for pickup.'
ELSE
SELECT @productKey, 'This product is available for shipping or pickup.'
Snowflake Scripting
DECLARE
MAXWEIGHT FLOAT;
PRODUCTKEY INTEGER;
BlockResultSet1 VARCHAR;
BlockResultSet2 VARCHAR;
return_arr ARRAY := array_construct();
BEGIN
MAXWEIGHT := 100.00;
PRODUCTKEY := 424;
IF (:MAXWEIGHT <= 99) THEN
BlockResultSet1 := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:BlockResultSet1) AS
SELECT
:PRODUCTKEY, 'This product is too heavy to ship and is only available for pickup.';
return_arr := array_append(return_arr, :BlockResultSet1);
ELSE
BlockResultSet2 := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:BlockResultSet2) AS
SELECT
:PRODUCTKEY, 'This product is available for shipping or pickup.';
return_arr := array_append(return_arr, :BlockResultSet2);
END IF;
--** SSC-FDM-0020 - MULTIPLE RESULT SETS ARE RETURNED IN TEMPORARY TABLES **
RETURN return_arr;
END;
Known Issues¶
문제가 발견되지 않았습니다.
관련 EWIs¶
SSC-EWI-0073: 보류 중 함수 동등성 검토.
SSC-FDM-0020: 여러 결과 세트가 임시 테이블에 반환됩니다.
LABEL 및 GOTO¶
Applies to
[x] SQL 서버
설명¶
Snowflake SQL 은 GOTO LABEL 문을 지원하지 않습니다. 현재 LABELS 에 설명이 추가되고 모든 발생에 대해 경고가 추가됩니다.
샘플 소스 패턴 ¶
다음 예제에서는 BEGIN 및 COMMIT 트랜잭션 문에 대해 자세히 설명합니다.
Transact-SQL ¶
CREATE PROCEDURE GoToProcedure
AS
BEGIN
DECLARE @TotalMaarks INT
SET @TotalMaarks = 49;
IF @TotalMaarks >= 50
GOTO Pass
IF @TotalMaarks < 50
GOTO Fail
Pass:
SELECT 1;
RETURN 1;
Fail:
SELECT 2;
RETURN 2;
END
Snowflake SQL ¶
CREATE OR REPLACE PROCEDURE GoToProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
TOTALMAARKS INT;
BEGIN
TOTALMAARKS := 49;
IF (:TOTALMAARKS >= 50) THEN
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'GOTO' NODE ***/!!!
GOTO Pass
END IF;
IF (:TOTALMAARKS < 50) THEN
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'GOTO' NODE ***/!!!
GOTO Fail
END IF;
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0045 - LABELED STATEMENT IS NOT SUPPORTED IN SNOWFLAKE SCRIPTING ***/!!!
Pass:
SELECT 1;
RETURN 1;
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0045 - LABELED STATEMENT IS NOT SUPPORTED IN SNOWFLAKE SCRIPTING ***/!!!
Fail:
SELECT 2;
RETURN 2;
END;
$$;
LABEL 및 GOTO 루틴 외부의 문(함수 및 프로시저)¶
Transact-SQL
CREATE TABLE T12(COL1 INT);
GOTO SecondStat
FirstStat:
INSERT INTO T12 VALUES (1);
SecondStat:
INSERT INTO T12 VALUES (2);
Snowflake Scripting
BEGIN
CREATE OR REPLACE TABLE T12 (
COL1 INT
);
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'Goto' NODE ***/!!!
GOTO SecondStat;
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0045 - LABELED STATEMENT IS NOT SUPPORTED IN SNOWFLAKE SCRIPTING ***/!!!
FirstStat:
INSERT INTO T12 VALUES (1);
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0045 - LABELED STATEMENT IS NOT SUPPORTED IN SNOWFLAKE SCRIPTING ***/!!!
SecondStat:
INSERT INTO T12 VALUES (2);
END;
Known Issues¶
문제가 발견되지 않았습니다.
관련 EWIs¶
SSC-EWI-TS0045: 레이블이 지정된 문은 Snowflake Scripting에서 지원되지 않습니다.
SSC-EWI-0073: 보류 중 함수 동등성 검토.
OUTPUT PARAMETERS¶
Applies to
[x] SQL 서버
[x] Azure 시냅스 분석
참고
출력 코드의 일부 부분은 명확성을 위해 생략되었습니다.
설명¶
출력 매개 변수 는 저장 프로시저에서 호출하는 SQL 블록으로 값이 다시 전달되는 매개 변수입니다. 출력 매개 변수는 Snowflake Scripting에서 지원되지 않으므로 해당 기능을 에뮬레이션하기 위한 솔루션이 구현되었습니다.
샘플 소스 패턴¶
단일 OUT 매개 변수¶
OUT 매개 변수에 대한 가장 기본적인 시나리오는 프로시저에 매개 변수가 하나만 있는 경우입니다. 이 경우 프로시저 본문 끝에 OUT 매개 변수를 반환하기만 하면 됩니다.
EXEC 프로시저도 변환해야 합니다. 이를 위해 CALL 이 생성되고, 매개 변수가 수정자 없이 전달되며(“OUT” 제거됨), 이후 매개 변수가 각각의 결과 값과 연관되도록 할당이 수행됩니다.
Transact-SQL¶
-- Procedure with output parameter
CREATE PROCEDURE dbo.outmain
@name VARCHAR (255) OUTPUT
AS
SET @name = 'Jane';
-- Auxiliary procedure that calls the main procedure
CREATE PROCEDURE dbo.outaux
AS
DECLARE @name VARCHAR (255);
EXEC dbo.outmain
@name = @name OUTPUT;
Snowflake Scripting¶
-- Procedure with output parameter
CREATE OR REPLACE PROCEDURE dbo.outmain (NAME STRING)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
NAME := 'Jane';
-- Auxiliary procedure that calls the main procedure
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'CREATE PROCEDURE' NODE ***/!!!
CREATE PROCEDURE dbo.outaux
AS
DECLARE @name VARCHAR (255);
EXEC dbo.outmain
@name = @name OUTPUT;
RETURN NAME;
END;
$$;
여러 OUT 매개 변수¶
OUT 매개 변수가 2개 이상 발견되면 프로시저의 RETURNS 절이 VARIANT 로 변경됩니다. 이는 OUT 매개 변수의 값을 저장하는 데 사용되는 OBJECT_CONSTRUCT 를 수용하기 위한 것입니다.
또한 프로시저 본문 끝에 RETURN 문이 추가됩니다. 여기에서 OBJECT_COSNTRUCT 가 생성되고 모든 OUT 매개 변수 값이 저장됩니다. 그러면 호출자는 이 오브젝트를 사용하여 해당 결과에 매개 변수 값을 할당합니다.
Transact-SQL¶
CREATE OR ALTER PROCEDURE basicProc (
@col1 INT OUT,
@col2 VARCHAR(10) OUT
) AS
BEGIN
SET @col1 = 4;
SET @col2 = 'test';
END;
CREATE OR ALTER PROCEDURE basicProcCall AS
BEGIN
DECLARE @var1 INT = 0;
DECLARE @var2 VARCHAR(10) = 'EMPTY';
EXEC basicProc @var1 OUT, @var2 OUT;
INSERT INTO TABLE1(col1, col2) VALUES (@var1, @var2);
END;
EXEC basicProcCall;
Snowflake Scripting¶
CREATE OR REPLACE PROCEDURE basicProc (COL1 INT, COL2 STRING)
RETURNS VARIANT
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
BEGIN
COL1 := 4;
COL2 := 'test';
END;
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'CREATE PROCEDURE' NODE ***/!!!
CREATE OR ALTER PROCEDURE basicProcCall AS
BEGIN
DECLARE @var1 INT = 0;
DECLARE @var2 VARCHAR(10) = 'EMPTY';
EXEC basicProc @var1 OUT, @var2 OUT;
INSERT INTO TABLE1(col1, col2) VALUES (@var1, @var2);
END;
EXEC basicProcCall;
RETURN OBJECT_CONSTRUCT('COL1', :COL1, 'COL2', :COL2);
END;
$$;
OUT 매개 변수 및 반환 값¶
Transact-SQL 에서는 프로시저에 반환 값을 가질 수 있습니다. 프로시저에 반환 값과OUT매개 변수가 모두 있는 경우다중OUT매개 변수 시나리오와 유사한 접근법을 따릅니다. 원래 반환 값은 OUT 매개 변수가 처리되는 방식으로 취급되므로 OBJECT_CONSTRUCT 내에 저장되고 호출자 프로시저 내부에서 추출됩니다.
Transact-SQL¶
-- Procedure with multiple output parameters
CREATE PROCEDURE dbo.outmain
@name VARCHAR (255) OUTPUT
AS
SET @name = 'Jane';
RETURN 0;
-- Auxiliary procedure that calls the main procedure
CREATE PROCEDURE dbo.outaux
AS
DECLARE @name VARCHAR (255);
DECLARE @returnValue INT;
EXEC @returnValue = dbo.outmain
@name = @name OUTPUT;
Snowflake Scripting¶
-- Procedure with multiple output parameters
CREATE OR REPLACE PROCEDURE dbo.outmain (NAME STRING)
RETURNS VARIANT
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
NAME := 'Jane';
RETURN OBJECT_CONSTRUCT('SC_RET_VALUE', 0, 'NAME', :NAME);
-- Auxiliary procedure that calls the main procedure
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'CREATE PROCEDURE' NODE ***/!!!
CREATE PROCEDURE dbo.outaux
AS
DECLARE @name VARCHAR (255);
DECLARE @returnValue INT;
EXEC @returnValue = dbo.outmain
@name = @name OUTPUT;
END;
$$;
고객 데이터 타입 OUT 매개 변수¶
출력 매개 변수가 고객 유형인 경우 프로세스는 일반 데이터 타입과 유사합니다.
Transact-SQL¶
CREATE PROCEDURE procedure_udtype_out_params(
@p_employee_id INT,
@p_phone [dbo].[PhoneNumber] OUTPUT
) AS
BEGIN
SELECT @p_phone = phone
FROM employees
WHERE employee_id = @p_employee_id;
END;
Snowflake Scripting¶
CREATE OR REPLACE PROCEDURE procedure_udtype_out_params (P_EMPLOYEE_ID INT, P_PHONE VARIANT /*** SSC-FDM-TS0015 - DATA TYPE DBO.PHONENUMBER IS NOT SUPPORTED IN SNOWFLAKE ***/)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
SELECT
phone
INTO
:P_PHONE
FROM
employees
WHERE
employee_id = :P_EMPLOYEE_ID;
RETURN P_PHONE;
END;
$$;
알려진 문제 ¶
문제가 발견되지 않았습니다.
관련 EWIs¶
SSC-EWI-0073: 보류 중 함수 동등성 검토.
SSC-FDM-TS0015: 데이터 타입은 Snowflake에서 지원되지 않습니다.
SET¶
Applies to
[x] SQL 서버
[x] Azure 시냅스 분석
설명¶
DECLARE @local_variable 문을 사용하여 이전에 생성한 지정한 로컬 변수를 지정한 값으로 설정합니다. Transact-SQL SET 에 대한 자세한 내용은 여기 를 확인하십시오.
다음과 같은 4가지 SET 케이스가 있습니다.
SET
{ @local_variable
[ . { property_name | field_name } ] = { expression | udt_name { . | :: } method_name }
}
|
{ @SQLCLR_local_variable.mutator_method
}
|
{ @local_variable
{+= | -= | *= | /= | %= | &= | ^= | |= } expression
}
|
{ @cursor_variable =
{ @cursor_variable | cursor_name
| { CURSOR [ FORWARD_ONLY | SCROLL ]
[ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]
[ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ]
[ TYPE_WARNING ]
FOR select_statement
[ FOR { READ ONLY | UPDATE [ OF column_name [ ,...n ] ] } ]
}
}
}
샘플 소스 패턴 ¶
Transact-SQL¶
CREATE OR ALTER PROCEDURE SetProcedure
AS
DECLARE @MyCounter INT;
DECLARE @FloatCounter FLOAT;
--Numerical operators
SET @MyCounter = 3;
SET @MyCounter += 1; --@MyCounter has 4
SET @MyCounter -= 1; --@MyCounter has 3
SET @MyCounter *= 2; --@MyCounter has 6
SET @MyCounter /= 3; --@MyCounter has 2
SET @MyCounter = 6;
SET @MyCounter /= 5; --@MyCounter has 1
SET @MyCounter = 6;
SET @MyCounter /= 7; --@MyCounter has 0
SET @FloatCounter = 10;
SET @FloatCounter /= 4; --@FloatCounter has 2.5
SET @MyCounter = 6;
SET @MyCounter %= 4; --@MyCounter has 2
--Logical operators
SET @MyCounter &= 3; --@MyCounter has 2
SET @MyCounter ^= 2; --@MyCounter has 0
SET @MyCounter |= 0; --@MyCounter has 0
RETURN @MyCounter;
GO
DECLARE @result INT;
EXEC @result = SetProcedure;
PRINT @result;
CREATE TABLE vEmployee (
PersonID int,
LastName varchar(255),
FirstName varchar(255)
);
CREATE OR ALTER PROCEDURE SetCursor
AS
DECLARE @CursorVar CURSOR;
SET @CursorVar = CURSOR SCROLL DYNAMIC
FOR
SELECT LastName, FirstName
FROM vEmployee
WHERE LastName like 'B%';
GO
|Result |
|---------|
|0 |
Snowflake Scripting <a href=”#expected-code”id=”expected-code”> ¶
CREATE OR REPLACE PROCEDURE SetProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
MYCOUNTER INT;
FLOATCOUNTER FLOAT;
BEGIN
--Numerical operators
MYCOUNTER := 3;
MYCOUNTER := MYCOUNTER + 1; --@MyCounter has 4
MYCOUNTER := MYCOUNTER - 1; --@MyCounter has 3
MYCOUNTER := MYCOUNTER * 2; --@MyCounter has 6
MYCOUNTER := TRUNC(MYCOUNTER / 3); --@MyCounter has 2
MYCOUNTER := 6;
MYCOUNTER := TRUNC(MYCOUNTER / 5); --@MyCounter has 1
MYCOUNTER := 6;
MYCOUNTER := TRUNC(MYCOUNTER / 7); --@MyCounter has 0
FLOATCOUNTER := 10;
FLOATCOUNTER := FLOATCOUNTER / 4; --@FloatCounter has 2.5
MYCOUNTER := 6;
MYCOUNTER := MYCOUNTER % 4; --@MyCounter has 2
--Logical operators
MYCOUNTER := BITAND(MYCOUNTER, 3); --@MyCounter has 2
MYCOUNTER := BITXOR(MYCOUNTER, 2); --@MyCounter has 0
MYCOUNTER := BITOR(MYCOUNTER, 0); --@MyCounter has 0
RETURN :MYCOUNTER;
END;
$$;
DECLARE
RESULT INT;
BEGIN
CALL SetProcedure();
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'Print' NODE ***/!!!
PRINT @result;
END;
CREATE OR REPLACE TABLE vEmployee (
PersonID INT,
LastName VARCHAR(255),
FirstName VARCHAR(255)
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
;
CREATE OR REPLACE PROCEDURE SetCursor ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0037 - SNOWFLAKE SCRIPTING CURSORS ARE NON-SCROLLABLE, ONLY FETCH NEXT IS SUPPORTED ***/!!!
--** SSC-FDM-TS0013 - SNOWFLAKE SCRIPTING CURSOR ROWS ARE NOT MODIFIABLE **
CURSORVAR CURSOR
FOR
SELECT LastName, FirstName
FROM vEmployee
WHERE LastName like 'B%';
BEGIN
RETURN '';
END;
$$;
|Result |
|---------|
|0 |
루틴 외부의 SET 문(함수 및 프로시저)¶
Transact-SQL 과 달리, Snowflake는 함수나 프로시저와 같은 루틴 외부에서 SET 같은 고립된 문을 실행하는 것을 지원하지 않습니다. 이 시나리오의 경우 다음 예시와 같이 문을 익명 블록으로 캡슐화해야 합니다. 이 문은 일반적으로 DECLARE STATEMENT 뒤에 사용합니다.
Transact-SQL¶
DECLARE @Group nvarchar(50), @Sales MONEY;
SET @Group = N'North America';
SET @Sales = 2000000;
Snowflake Scripting
DECLARE
_GROUP VARCHAR(50);
SALES NUMBER(38, 4);
BEGIN
_GROUP := 'North America';
SALES := 2000000;
END;
SET 문으로만 구성된 시나리오가 있는 경우 DECLARE 블록은 필요하지 않습니다. 이 시나리오에서 선언되지 않은 변수에 값을 설정하려고 하면 런타임 오류가 발생할 수 있습니다.
Transact-SQL¶
SET @Group = N'North America';
Snowflake Scripting
BEGIN
_GROUP := 'North America';
END;
Known Issues¶
1. SET of a local variable with property name¶
이 유형의 세트는 현재 Snowflake 스크립팅에서 지원되지 않습니다.
// TSQL custom data type with properties example
DECLARE @p Point;
SET @p.X = @p.X + 1.1;
2. SET of a local variable with mutator method¶
이 유형의 세트는 현재 Snowflake 스크립팅에서 지원되지 않습니다.
// TSQL custom data type with mutator method
SET @p.SetXY(22, 23);
관련 EWIs¶
SSC-EWI-TS0037: Snowflake Scripting 커서는 스크롤할 수 없습니다.
SSC-EWI-0073: 보류 중 함수 동등성 검토.
SSC-FDM-TS0013: Snowflake Scripting 커서 행은 수정할 수 없습니다.
TRY CATCH¶
Applies to
[x] SQL 서버
[x] Azure 시냅스 분석
설명¶
Transact SQL 에 대한 오류 처리를 구현합니다. Transact-SQL 문 그룹은 TRY 블록으로 묶을 수 있습니다. TRY 블록에서 오류가 발생하면 일반적으로 CATCH 블록으로 묶인 다른 문 그룹으로 컨트롤이 전달됩니다.
샘플 소스 패턴 ¶
다음 예제에서는 TRY CATCH 내부 프로시저에 대한 변환을 자세히 설명합니다.
Transact-SQL ¶
CREATE PROCEDURE ERROR_HANDLING_PROC
AS
BEGIN
BEGIN TRY
-- Generate divide-by-zero error.
SELECT 1/0;
END TRY
BEGIN CATCH
-- Execute error retrieval routine.
SELECT 'error';
END CATCH;
END;
|error |
Snowflake SQL ¶
CREATE OR REPLACE PROCEDURE ERROR_HANDLING_PROC ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
BEGIN
-- Generate divide-by-zero error.
SELECT
TRUNC( 1/0);
EXCEPTION
WHEN OTHER THEN
-- Execute error retrieval routine.
SELECT 'error';
END;
END;
$$;
|error |
외부 루틴(함수 및 프로시저)을 잡아보십시오¶
Transact-SQL
BEGIN TRY
SELECT 1/0;
END TRY
BEGIN CATCH
SELECT 'error';
END CATCH;
Snowflake Scripting
DECLARE
BlockResultSet1 VARCHAR;
BlockResultSet2 VARCHAR;
return_arr ARRAY := array_construct();
BEGIN
BEGIN
BlockResultSet1 := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:BlockResultSet1) AS
SELECT
TRUNC( 1/0);
return_arr := array_append(return_arr, :BlockResultSet1);
EXCEPTION
WHEN OTHER THEN
BlockResultSet2 := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:BlockResultSet2) AS
SELECT 'error';
return_arr := array_append(return_arr, :BlockResultSet2);
END;
--** SSC-FDM-0020 - MULTIPLE RESULT SETS ARE RETURNED IN TEMPORARY TABLES **
RETURN return_arr;
END;
Known Issues¶
문제가 발견되지 않았습니다.
관련 EWIs¶
SSC-FDM-0020: 여러 결과 세트가 임시 테이블에 반환됩니다.
WHILE¶
Applies to
[x] SQL 서버
[x] Azure 시냅스 분석
설명 ¶
While 문은 지정된 조건이 true이면 SQL 문 또는 문 블록을 반복적으로 실행할 수 있습니다. WHILE 루프에서 문의 실행은 BREAK
및 CONTINUE
키워드를 사용하여 루프 내부에서 제어할 수 있습니다.
Transact-SQL 에 대한 자세한 내용은 여기 를 확인하십시오.
WHILE Boolean_expression
{ sql_statement | statement_block | BREAK | CONTINUE }
참고: 문 블록을 정의하려면 플로우 제어 키워드 BEGIN
및 END
를 사용합니다.
샘플 소스 패턴 ¶
기본 소스 패턴 코드¶
Transact-SQL ¶
다음 코드는 @Iteration 변수를 반복하고 @Iteration 값이 10이 되면 종료되도록 루프의 흐름을 제어하는 Transact-SQL 의 While Loop를 참조합니다.
참고
CONTINUE
키워드 뒤에 오는 문은 실행되지 않습니다.
CREATE OR ALTER PROCEDURE WhileDemoProcedure
AS
DECLARE @iteration INT;
SET @iteration = 1;
WHILE @iteration < 100
BEGIN
IF @iteration = 10
BREAK;
ELSE
BEGIN
SET @iteration = @iteration + 1;
CONTINUE;
SET @iteration = 2 * @iteration;
END;
END;
RETURN @iteration;
GO
DECLARE @result INT;
EXEC @result = WhileDemoProcedure;
PRINT @result;
|iteration|
|---------|
|10 |
Snowflake Scripting <a href=”#expected-code”id=”expected-code”> ¶
참고
Transact-SQL 뿐만 아니라, Snowflake Scripting에서 CONTINUE
키워드 뒤의 문은 실행되지 않습니다.
Snowflake Scripting에서는 BEGIN 및 END 키워드를 사용하여 문 블록을 정의할 필요는 없지만 필요한 경우 이 키워드를 사용할 수 있습니다.
CREATE OR REPLACE PROCEDURE WhileDemoProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
ITERATION INT;
BEGIN
ITERATION := 1;
WHILE (:ITERATION < 100) LOOP
IF (:ITERATION = 10) THEN
BREAK;
ELSE
BEGIN
ITERATION := :ITERATION + 1;
CONTINUE;
ITERATION := 2 * :ITERATION;
END;
END IF;
END LOOP;
RETURN :ITERATION;
END;
$$;
DECLARE
RESULT INT;
BEGIN
CALL WhileDemoProcedure();
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'Print' NODE ***/!!!
PRINT @result;
END;
Snowflake Scripting을 사용하면 DO
대신 LOOP
키워드를, END WHILE
대신 END LOOP
식을 사용할 수 있습니다.
WHILE (Boolean_expression) LOOP
-- statement or statement block
END LOOP;
|Iteration|
|---------|
|10 |
본문이 비어있는 While 소스 패턴¶
Transact-SQL ¶
참고
이 예제는 IF ELSE 문이 지원되지 않는 상태에서 작성된 것으로, 해당 문이 지원되면 결과의 차이가 사라질 것입니다.
CREATE OR ALTER PROCEDURE WhileEmptyBodyProc
AS
BEGIN
DECLARE @MyVar INT;
SET @MyVar = 1;
WHILE (@MyVar < 100)
BEGIN
IF @MyVar < 50
SET @MyVar *= 5;
ELSE
SET @MyVar *= 3;
END;
RETURN @MyVar;
END;
DECLARE @result INT;
EXEC @result = WhileEmptyBodyProc;
PRINT @result;
|result|
|------|
|125 |
Snowflake Scripting¶
이 문은 Snowflake Scripting에서 빈 본문을 가질 수 없으며, 이러한 경우를 해결하기 위해 빈 본문이 감지되면 기본 BREAK 문이 추가됩니다.
CREATE OR REPLACE PROCEDURE WhileEmptyBodyProc ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
MYVAR INT;
RESULT INT;
BEGIN
BEGIN
MYVAR := 1;
WHILE (:MYVAR < 100) LOOP
IF (:MYVAR < 50) THEN
MYVAR := MYVAR * 5;
ELSE
MYVAR := MYVAR * 3;
END IF;
END LOOP;
RETURN :MYVAR;
END;
CALL WhileEmptyBodyProc();
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'PRINT' NODE ***/!!!
PRINT @result;
END;
$$;
|result|
|------|
|1 |
루틴 외부의 WHILE 문(함수 및 프로시저)¶
Transact-SQL 과 달리, Snowflake는 함수나 프로시저와 같은 루틴 외부에서 WHILE 같은 고립된 문을 실행하는 것을 지원하지 않습니다. 이 시나리오의 경우 다음 예시와 같이 문을 익명 블록으로 캡슐화해야 합니다.
Transact-SQL ¶
DECLARE @iteration INT;
SET @iteration = 1;
WHILE @iteration < 100
BEGIN
IF @iteration = 10
BREAK;
ELSE
BEGIN
SET @iteration = @iteration + 1;
CONTINUE;
SET @iteration = 2 * @iteration;
END;
END;
Snowflake Scripting
DECLARE
ITERATION INT;
BEGIN
ITERATION := 1;
WHILE (:ITERATION < 100) LOOP
IF (:ITERATION = 10) THEN
BREAK;
ELSE
BEGIN
ITERATION := :ITERATION + 1;
CONTINUE;
ITERATION := 2 * :ITERATION;
END;
END IF;
END LOOP;
END;
Known Issues¶
문제가 발견되지 않았습니다.
관련 EWIs¶
SSC-EWI-0073: 보류 중 함수 동등성 검토.