SnowConvert: Snowflake Scripting

BEGIN および COMMIT トランザクション

Applies to
  • [x] SQL Server

  • [x] Azure Synapse Analytics

説明

Snowflake SQL、BEGIN ステートメントを実行することで、トランザクションを明示的に開始することができます。Snowflakeは、同義語 BEGIN WORKBEGIN 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
Copy
 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
Copy
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;
$$;
Copy
 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;
$$;
Copy

既知の問題

  1. ネストされたトランザクションは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
Copy

注意: 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;
Copy
 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;
Copy
 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|
Copy
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();
Copy
 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();
Copy
 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|
Copy

ケースを使用したセット

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;
Copy
 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;
Copy
 |result|
|------|
|150   |
Copy
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;
Copy
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;
Copy
 |result|
|------|
|150   |
Copy

既知の問題

問題は見つかりませんでした。

関連 EWIs

  1. 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 ] }
[;]
Copy

サンプルソースパターン

本文のないストアドプロシージャ

本文のないストアドプロシージャは、Transact-SQL で許可されている珍しいシナリオです。Snowflake Scriptingでは、本文のないプロシージャを定義することはできませんが、次の例では同等であることを示しています。

Transact-SQL
 CREATE PROC SampleProcedure AS;
Copy
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;
$$;
Copy

基本ストアドプロシージャ

次の例は、AdventureWorks2019 データベースに新しいプライバシー部門を追加する単純なストアドプロシージャの詳細です。

Transact-SQL
 CREATE OR ALTER PROCEDURE Add_Privacy_Department
AS
  EXECUTE ('INSERT INTO HumanResources.Department VALUES (''Privacy'', ''Executive General and Administration'', default)');
Copy
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;
$$;
Copy

プロシージャの変更

ALTER プロシージャの変換は、基本プロシージャと同等です。

Transact-SQL
 ALTER PROCEDURE procedureName
AS
SELECT 1 AS ThisDB;
Copy
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;
$$;
Copy

パラメーターの使用

パラメーターを使用してロジックを推進したり、ストアドプロシージャ内で動的な 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;
Copy
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;
$$;
Copy

出力パラメーター

Transact-SQL 出力キーワードは、パラメーターが出力パラメーターであることを示し、その値はストアドプロシージャ呼び出し元に返されます。例えば、以下のプロシージャは、特定の従業員の休暇時間数を返します。

Transact-SQL
 CREATE PROCEDURE GetVacationHours  
   @employeeId INT,  
   @vacationHours INT OUTPUT  
AS  
BEGIN  
   SELECT @vacationHours = VacationHours 
   FROM HumanResources.Employee
   WHERE NationalIDNumber = @employeeID
END;
Copy
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;
$$;
Copy

警告

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
Copy
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);
Copy

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;
Copy
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;
$$;
Copy
  • 発信者

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;
Copy
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;
$$;
Copy

警告

SELF や特定のユーザー('user_name')の実行コンテキストは、Snowflake Scriptingではサポートされていません。

READONLY AND VARYING PARAMETERS

Snowflakeは READONLYVARYING のパラメーター型をサポートしていません。代わりに FDM が追加されています。

Transact-SQL
 CREATE OR ALTER PROCEDURE GetVacationHours
   @Param1 INT READONLY,  
   @Param2 INT VARYING
AS
BEGIN  
   SELECT * FROM Table1;
END;
Copy
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;
$$;
Copy

既知の問題

サポートされていないオプション引数

  • [VARYING] カーソル パラメーターにのみ適用されます。出力パラメーターとしてサポートされる結果セットを指定します。このパラメーターはプロシージャによって動的に作成され、その内容は変化する可能性があります。Snowflake Scriptingは有効な戻り値のデータ型として CURSOR をサポートしていません。

  • [= default] デフォルト値を定義することで、パラメーターをオプションにします。Snowflake Scriptingは、デフォルトのパラメーター値をネイティブにサポートしていません。

  • [READONLY] プロシージャ本文内でパラメーターを更新または変更できないことを示します。現在Snowflake Scriptingではサポートされていません。

  • [WITH RECOMPILE] ストアドプロシージャが実行されるたびに、データベースエンジンにストアドプロシージャのクエリプランをコンパイルさせます。現在Snowflake Scriptingではサポートされていません。

  • [WITH ENCRYPTION] ストアドプロシージャのテキストを暗号化するために使用します。システムテーブルやデータベースファイルにアクセスできるユーザー(システム管理ユーザーなど)のみが、プロシージャの作成後にプロシージャテキストにアクセスすることができます。現在Snowflake Scriptingではサポートされていません。

  • [FOR REPLICATION] ストアドプロシージャが複製中にのみ実行されるように制限します。現在Snowflake Scriptingではサポートされていません。

関連 EWIS

  1. SSC-EWI-0030: 以下のステートメントには、動的 SQL の使用があります。

  2. 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 ] ] ]  
[;]  
Copy
 FETCH   
          [ [ NEXT | PRIOR | FIRST | LAST   
                    | ABSOLUTE { n | @nvar }   
                    | RELATIVE { n | @nvar }   
               ]   
               FROM   
          ]   
{ { [ GLOBAL ] cursor_name } | @cursor_variable_name }   
[ INTO @variable_name [ ,...n ] ] 
Copy
 OPEN { { [ GLOBAL ] cursor_name } | cursor_variable_name }  
Copy
 CLOSE { { [ GLOBAL ] cursor_name } | cursor_variable_name }
Copy
 DEALLOCATE { { [ GLOBAL ] cursor_name } | @cursor_variable_name }  
Copy

サンプルソースパターン

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
Copy
B

Copy
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;
$$;
Copy
B

Copy

既知の問題

以下のパラメーターはサポートされていません。

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;
Copy
 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;
$$;
Copy

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
Copy

環境変数

  • @@CURSOR_ROWS

  • @@FETCH_STATUS

関連 EWIs

  1. SSC-FDM-TS0013: Snowflake Scriptingのカーソル行は変更できません。

  2. 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 )   
     }
Copy

サンプルソースパターン

変数の宣言

変数はさまざまな方法で作成できます。変数にはデフォルト値があってもなくてもよく、同じ行で複数の変数を宣言することができます。

Snowflake Scriptingでは、1行に複数の変数を作成できないことに注意してください。

Transact-SQL
 DECLARE @find VARCHAR(30);
DECLARE @find2 VARCHAR(30) = 'Default';
DECLARE @var VARCHAR(5), @var2 varchar(5);
Copy

Snowflake Scripting

 DECLARE
FIND VARCHAR(30);
FIND2 VARCHAR(30) := 'Default';
VAR VARCHAR(5);
VAR2 VARCHAR(5);
BEGIN
RETURN '';
END;
Copy

テーブル変数の宣言

Transact-SQL では、通常のテーブルとして使用できるテーブル変数の作成が可能です。Snowflake Scriptingはこれをサポートしませんが、代わりにテーブルを作成し、プロシージャの最後にドロップすることができます。

Transact-SQL
 DECLARE @MyTableVar TABLE(  
    column1 varchar(10));
Copy

Snowflake Scripting

 BEGIN
    DECLARE
        T_MYTABLEVAR TABLE(
            column1 VARCHAR(10));
END;
Copy

ルーチン(関数とプロシージャ)外の DECLARE ステートメント

Transact-SQL と異なり、Snowflakeは関数やプロシージャのようなルーチンの外側で DECLARE のような分離ステートメントを実行することをサポートしていません。このシナリオでは、ステートメントは次の例に示すように匿名ブロックにカプセル化する必要があります。このステートメントは通常SET STATEMENTの前に使われます。

Transact-SQL
 DECLARE @Group nvarchar(50), @Sales MONEY;
SET @Group = N'North America';
SET @Sales = 2000000;
Copy

Snowflake Scripting

 DECLARE
_GROUP VARCHAR(50);
SALES NUMBER(38, 4);
BEGIN
_GROUP := 'North America';
SALES := 2000000;
END;
Copy

DECLARE ステートメントのみを含むシナリオがある場合、このブロックは空にすることができないために、エラーを回避するために BEGIN...END ブロックに RETURN NULL ステートメントが必要です。

Transact-SQL
 DECLARE @Group nvarchar(50), @Sales MONEY;
Copy

Snowflake Scripting

 DECLARE
_GROUP VARCHAR(50);
SALES NUMBER(38, 4);
BEGIN
RETURN '';
END;
Copy

既知の問題

問題は見つかりませんでした。

関連 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 ] ]  
    }  
[;]  
Copy

サンプルソースパターン

文字列の実行

EXECUTE を使うと、リテラルとして直接渡された SQL の操作を実行できます。以下の例では、AdventureWorks2019 データベースに新しいプライバシー部門を挿入するストアドプロシージャの中で使用されています。

Transact-SQL
 CREATE OR ALTER PROCEDURE AddPrivacyDepartment
AS 
EXECUTE ('INSERT INTO HumanResources.Department VALUES (''Privacy'', ''Executive General and Administration'', default)');
Copy
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;
$$;
Copy

ストアドプロシージャの実行

EXECUTE を使用して既存のストアドプロシージャを呼び出すこともできます。次の例では、上で作成した AddPrivacyDepartment プロシージャを呼び出します。その後、SELECT を実行し、新しい部門が正常に組み込まれたことを確認します。

Transact-SQL
 EXECUTE AddPrivacyDepartment;
SELECT DepartmentID, Name, GroupName FROM HumanResources.Department; 
Copy
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|

Copy
Snowflakeスクリプト
 CALL AddPrivacyDepartment();

SELECT
DepartmentID,
Name,
GroupName
FROM
HumanResources.Department;
Copy
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|

Copy

ローカル変数の実行とパラメーターの使用

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;
Copy
ListPrice|
---------+
  34.9900|

Copy
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;
Copy
LISTPRICE|
---------+
  34.9900|

Copy

既知の問題

リターンコードの使用

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;
Copy
ListPrice|
---------+
  34.0928|

Copy
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;
Copy

サポートされていないオプション引数

  • @return_status

  • ;number

  • @module__name_v_ar

  • WITH RECOMPILE、WITH RESULT SETS NONE、WITH <結果セット定義>

関連 EWIs

  1. 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 } ]   
Copy

注意: ステートメントブロックを定義するには、フロー制御キーワード BEGINEND を使用します。

サンプルソースパターン

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;
Copy
 |result|
|------|
|200   |
Copy
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;
Copy
|result|
|------|
|200   |

Copy

ルーチン(関数とプロシージャ)外の 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.' 
Copy

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;
Copy

既知の問題

問題は見つかりませんでした。

関連 EWIs

  1. SSC-EWI-0073: 機能同等性レビュー保留中。

  2. 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
Copy
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;
$$;
Copy

ルーチン(関数とプロシージャ)外の LABEL および GOTO ステートメント

Transact-SQL

 CREATE TABLE T12(COL1 INT);
GOTO SecondStat
FirstStat:
    INSERT INTO T12 VALUES (1);
SecondStat:
    INSERT INTO T12 VALUES (2);
Copy

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;
Copy

既知の問題

問題は見つかりませんでした。

関連 EWIs

  1. SSC-EWI-TS0045: ラベル付きステートメントはSnowflake Scriptingではサポートされていません。

  2. 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;
Copy
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;
$$;
Copy

複数の 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;
Copy
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;
$$;
Copy

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;
Copy
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;
$$;
Copy

顧客データ型 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;
Copy
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;
$$;
Copy

既知の問題

問題は見つかりませんでした。

関連 EWIs

  1. SSC-EWI-0073: 機能同等性レビュー保留中。

  2. 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 ] ] } ]   
      }   
    }  
}
Copy

サンプルソースパターン

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;
Copy
 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	
Copy
|Result   |
|---------|
|0        |

Copy
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;
Copy
 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;
$$;
Copy
|Result   |
|---------|
|0        |

Copy

ルーチン(関数とプロシージャ)外の SET ステートメント

Transact-SQL と異なり、Snowflakeは関数やプロシージャのようなルーチンの外側で SET のような分離ステートメントを実行することをサポートしていません。このシナリオでは、ステートメントは次の例に示すように匿名ブロックにカプセル化する必要があります。このステートメントは通常、DECLARE STATEMENTの後に使用します。

Transact-SQL
 DECLARE @Group nvarchar(50), @Sales MONEY;
SET @Group = N'North America';
SET @Sales = 2000000;
Copy

Snowflake Scripting

 DECLARE
_GROUP VARCHAR(50);
SALES NUMBER(38, 4);
BEGIN
_GROUP := 'North America';
SALES := 2000000;
END;
Copy

SET ステートメントだけのシナリオであれば、DECLARE ブロックは必要ありません。おそらくこのシナリオでは、宣言されていない変数に値をセットしようとするとランタイムエラーが発生します。

Transact-SQL
 SET @Group = N'North America';
Copy

Snowflake Scripting

 BEGIN
_GROUP := 'North America';
END;
Copy

既知の問題

1.プロパティ名を持つローカル変数の SET

このタイプのセットは、現在Snowflake Scriptingではサポートされていません。

 // TSQL custom data type with properties example 
DECLARE @p Point;  
SET @p.X = @p.X + 1.1;  
Copy
2.ミューテーターメソッドを持つローカル変数の SET

このタイプのセットは、現在Snowflake Scriptingではサポートされていません。

 // TSQL custom data type with mutator method
SET @p.SetXY(22, 23);   
Copy

関連 EWIs

  1. SSC-EWI-TS0037: Snowflake Scriptingカーソルはスクロールできません。

  2. SSC-EWI-0073: 機能同等性レビュー保留中。

  3. 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;
Copy
|error    |

Copy
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;
$$;
Copy
|error    |

Copy

ルーチン(関数とプロシージャ)の外側のtry catch

Transact-SQL

 BEGIN TRY  
    SELECT 1/0;  
END TRY  
BEGIN CATCH  
    SELECT 'error';
END CATCH;
Copy

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;
Copy

既知の問題

問題は見つかりませんでした。

関連 EWIs

  1. SSC-FDM-0020: 仮テーブルに複数の結果セットが返されます。

WHILE

Applies to
  • [x] SQL Server

  • [x] Azure Synapse Analytics

説明

Whileステートメントを使用すると、SQL ステートメントまたはステートメントのブロックを、指定された条件がtrueである限り繰り返し実行することができます。WHILE ループ内のステートメントの実行は、ループ内部から BREAKCONTINUE キーワードで制御できます。

Transact-SQL Whileの詳細情報については、こちら をご覧ください。

 WHILE Boolean_expression   
     { sql_statement | statement_block | BREAK | CONTINUE }
Copy

注意: ステートメントブロックを定義するには、フロー制御キーワード BEGINEND を使用します。

サンプルソースパターン

基本ソースパターンコード

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;
Copy
|iteration|
|---------|
|10       |

Copy
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 &#x3C; 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;
Copy

Snowflake Scriptingでは、DO の代わりに LOOP キーワードを、END WHILE の代わりに END LOOP 式を使用することができます。

 WHILE (Boolean_expression) LOOP
    -- statement or statement block
END LOOP;
Copy
|Iteration|
|---------|
|10       |

Copy

空の本文ソースパターンを持つ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;
Copy
|result|
|------|
|125   |

Copy
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;
$$;
Copy
|result|
|------|
|1     |

Copy

ルーチン(関数とプロシージャ)外の 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;
Copy

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;
Copy

既知の問題

問題は見つかりませんでした。

関連 EWIs

  1. SSC-EWI-0073: 機能同等性レビュー保留中。