web-dev-qa-db-ja.com

TVFは内部で複数のCTEステートメントを使用できますか?

マルチステートメントテーブル値関数を作成しようとしていますが、関数とCTEの制限であると思われるために失敗します。

目的の関数は、入力パラメーター(@Param)と出力テーブル(@ResultTable)を定義します。

次に、セミコロンで終了する(必然的に)そのテーブル変数へのCTEを含む複雑な挿入ステートメントを実行します。

次に、CTEを含むそのテーブル変数に対して別の複雑な更新ステートメントを試行すると、「スカラー変数「@ResultTable」を宣言する必要があります」というエラーが表示されます。どうやらスコープから外れているようです。

私は過去にこの種のパターンを使用したことがあるので、私の唯一の考えは、CTEが何らかの方法でスコープを制限しているように見えるということです。これは既知の制限ですか?

1
Jeff Sacksteder

次の石畳の例を使用して、3つの異なるCTEを利用して、出力テーブル変数を処理することができます。おそらく、プロセスとこの単純な例の違いを特定できますか?

IF EXISTS (SELECT *
           FROM   sys.objects
           WHERE  object_id = OBJECT_ID(N'[dbo].[TEST_TVF_CTE]')
                  AND type IN ( N'FN', N'IF', N'TF', N'FS', N'FT' ))
  DROP FUNCTION [dbo].[TEST_TVF_CTE]

GO 
CREATE FUNCTION [dbo].[TEST_TVF_CTE] (@sInputList VARCHAR(8000))
RETURNS @OutTable TABLE (item VARCHAR(8000))

BEGIN
    WITH FIRSTCTE
    AS (
        SELECT TOP 1 TABLE_NAME
        FROM INFORMATION_SCHEMA.TABLES
        ORDER BY TABLE_NAME
        )
    INSERT INTO @OutTable
    SELECT *
    FROM FIRSTCTE;

    WITH SECONDCTE
    AS (
        SELECT TOP 1 TABLE_NAME
        FROM INFORMATION_SCHEMA.TABLES
        ORDER BY TABLE_NAME DESC
        )
    INSERT INTO @OutTable
    SELECT *
    FROM SECONDCTE;

    WITH FINALCTE
    AS (
        SELECT TOP 1 'XYZ' AS TABLE_NAME
        FROM INFORMATION_SCHEMA.TABLES
        ORDER BY TABLE_NAME DESC
        )
    UPDATE a
    SET a.item = b.table_name
    FROM @OutTable a
    JOIN FINALCTE b ON 1 = 1

    RETURN
END
GO

SELECT *
FROM DBO.TEST_tvf_cte('...')
1
Scott Hodgin