SnowConvert: Snowflake Scripting¶
BEGIN および COMMIT トランザクション¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
説明¶
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;
$$;
既知の問題¶
ネストされたトランザクションはSnowflakeではサポートされていません。詳しくは以下のドキュメントをご覧ください: https://docs.snowflake.com/en/sql-reference/transactions
CALL¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
説明¶
CALL ステートメントは、ODBC API の一部であり、SQL ステートメントではないため、Snowflake Scriptingではサポートされておらず、このステートメントは翻訳されません。
CASE¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
注釈
わかりやすくするため、出力コードの一部を省略しています。
説明¶
Transact-SQL には、ケース式の形式が2つあります。どちらも式を評価し、条件付きで結果を取得するために使用されます。最初のものは、input_expressionがwhen_expressionの1つ以上に一致するかどうかを評価する単純なケース式を参照します。2番目は、各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 では、オプションでinput_expressionとboolean_expressionを括弧でカプセル化できます。Snowflake Scriptingでも同様です。
サンプルソースパターン¶
次の例では、ケース式を使用できる2つのシナリオと、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 ¶
このシナリオでは、ケース式自体に違いはないことに注意してください。
警告
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 ¶
警告
Snowflake Scriptingでは、ケース式を直接変数にセットすることはできません。Transact-SQL ケース式のどちらの形式も、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 |
既知の問題¶
問題は見つかりませんでした。
関連 EWIs¶
SSC-EWI-0073: 機能同等性レビュー保留中。
CREATE PROCEDURE¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
注釈
わかりやすくするため、出力コードの一部を省略しています。
説明¶
プロシージャの作成ステートメントを使用すると、次の機能を備えたストアドプロシージャを作成できます。
入力パラメーターを受け取り、複数の値を出力パラメーターとして呼び出しプロシージャまたはバッチに返します。
他のプロシージャの呼び出しを含む、データベース内で操作を実行するプログラミングステートメントが含まれます。
成功または失敗(および失敗の理由)を示すステータス値を呼び出しプロシージャまたはバッチに返します。
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スクリプト¶
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スクリプト¶
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スクリプト¶
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スクリプト¶
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スクリプト¶
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 Scriptingのストアドプロシージャから返せる出力パラメーターは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スクリプト¶
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スクリプト¶
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スクリプト¶
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スクリプト¶
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;
$$;
既知の問題¶
サポートされていないオプション引数¶
[VARYING] カーソル パラメーターにのみ適用されます。出力パラメーターとしてサポートされる結果セットを指定します。このパラメーターはプロシージャによって動的に作成され、その内容は変化する可能性があります。Snowflake Scriptingは有効な戻り値のデータ型として CURSOR をサポートしていません。
[= default] デフォルト値を定義することで、パラメーターをオプションにします。Snowflake Scriptingは、デフォルトのパラメーター値をネイティブにサポートしていません。
[READONLY] プロシージャ本文内でパラメーターを更新または変更できないことを示します。現在Snowflake Scriptingではサポートされていません。
[WITH RECOMPILE] ストアドプロシージャが実行されるたびに、データベースエンジンにストアドプロシージャのクエリプランをコンパイルさせます。現在Snowflake Scriptingではサポートされていません。
[WITH ENCRYPTION] ストアドプロシージャのテキストを暗号化するために使用します。システムテーブルやデータベースファイルにアクセスできるユーザー(システム管理ユーザーなど)のみが、プロシージャの作成後にプロシージャテキストにアクセスすることができます。現在Snowflake Scriptingではサポートされていません。
[FOR REPLICATION] ストアドプロシージャが複製中にのみ実行されるように制限します。現在Snowflake Scriptingではサポートされていません。
関連 EWIS¶
SSC-EWI-0030: 以下のステートメントには、動的 SQL の使用があります。
SSC-EWI-0058: この関数は現在Snowflake Scriptingではサポートされていません。
CURSOR¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
注釈
わかりやすくするため、出力コードの一部を省略しています。
説明¶
Transact-SQL ステートメントは完全な結果セットを生成しますが、結果を1行ずつ処理するのが最適な場合もあります。結果セット上でカーソルを開くと、結果セットを一度に1行ずつ処理することができます。 カーソル データ型を持つ変数またはパラメーターにカーソルを割り当てることができます。詳細は こちら をご覧ください。
//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スクリプト¶
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
既知の問題¶
以下のパラメーターはサポートされていません。
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では、ローカルでのみカーソルを使用できます。
INTO のない FETCH はサポートされていません。
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: ループ内のフェッチは複雑なパターンとみなされるため、Snowflakeのパフォーマンスが低下する可能性があります。
DECLARE¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
説明¶
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では、1行に複数の変数を作成できないことに注意してください。
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;
既知の問題¶
問題は見つかりませんでした。
関連 EWIs¶
関連 EWIs はありません。
EXECUTE¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
注釈
わかりやすくするため、出力コードの一部を省略しています。
説明¶
Transact-SQL EXECUTE ステートメントを使用すると、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スクリプト¶
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スクリプト¶
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スクリプト¶
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|
既知の問題¶
リターンコードの使用¶
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スクリプト¶
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 Server
[x] Azure Synapse Analytics
説明¶
IF 句は、SQL ステートメントまたはステートメントのブロックを、ブール式がtrueである限り条件付きで実行することを可能にします。そうでない場合は、オプションの 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¶
次のコードは、変数@valueが5より小さいか、5以上10以下か、あるいはそれ以外の値かを識別するために、変数@valueを条件付けるTransact-SQL の IF... ELSE を参照しています。@valueは7として初期化されているので、2番目の条件は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 ¶
注釈
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;
既知の問題¶
問題は見つかりませんでした。
関連 EWIs¶
SSC-EWI-0073: 機能同等性レビュー保留中。
SSC-FDM-0020: 仮テーブルに複数の結果セットが返されます。
LABEL および GOTO¶
Applies to
[x] SQL Server
説明¶
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;
既知の問題¶
問題は見つかりませんでした。
関連 EWIs¶
SSC-EWI-TS0045: ラベル付きステートメントはSnowflake Scriptingではサポートされていません。
SSC-EWI-0073: 機能同等性レビュー保留中。
OUTPUT PARAMETERS¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
注釈
わかりやすくするため、出力コードの一部を省略しています。
説明¶
出力パラメーター は、ストアドプロシージャから呼び出し元の SQL ブロックに値が渡されるパラメーターです。出力パラメーターはSnowflake Scriptingではサポートされていないため、その機能をエミュレートするためのソリューションが実装されています。
サンプルソースパターン¶
単一の OUT パラメーター¶
OUT パラメーターの最も基本的なシナリオは、プロシージャにパラメーターが1つしかない場合です。この場合、プロシージャ本文の最後に 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スクリプト¶
-- 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 パラメーターが複数見つかった場合、プロシージャの 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スクリプト¶
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スクリプト¶
-- 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スクリプト¶
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 Server
[x] Azure Synapse Analytics
説明¶
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 ¶
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;
既知の問題¶
1.プロパティ名を持つローカル変数の SET¶
このタイプのセットは、現在Snowflake Scriptingではサポートされていません。
// TSQL custom data type with properties example
DECLARE @p Point;
SET @p.X = @p.X + 1.1;
2.ミューテーターメソッドを持つローカル変数の SET¶
このタイプのセットは、現在Snowflake Scriptingではサポートされていません。
// 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 Server
[x] Azure Synapse Analytics
説明¶
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 |
ルーチン(関数とプロシージャ)の外側のtry catch¶
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;
既知の問題¶
問題は見つかりませんでした。
関連 EWIs¶
SSC-FDM-0020: 仮テーブルに複数の結果セットが返されます。
WHILE¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
説明¶
Whileステートメントを使用すると、SQL ステートメントまたはステートメントのブロックを、指定された条件がtrueである限り繰り返し実行することができます。WHILE ループ内のステートメントの実行は、ループ内部から BREAK
と CONTINUE
キーワードで制御できます。
Transact-SQL Whileの詳細情報については、こちら をご覧ください。
WHILE Boolean_expression
{ sql_statement | statement_block | BREAK | CONTINUE }
注意: ステートメントブロックを定義するには、フロー制御キーワード BEGIN
と END
を使用します。
サンプルソースパターン¶
基本ソースパターンコード¶
Transact-SQL ¶
次のコードは、Transact-SQL のWhileループを参照しています。変数@Iterationを繰り返し処理し、@Iterationの値が10になったときにループが終了するようにフローを制御します。
注釈
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 ¶
注釈
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スクリプト¶
このステートメントは、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;
既知の問題¶
問題は見つかりませんでした。
関連 EWIs¶
SSC-EWI-0073: 機能同等性レビュー保留中。