2

動的ピボットを使用して、期待している形式でデータを返す次のクエリがあります。

CREATE TABLE TEMPDOCS (DOCID INT, NAME VARCHAR(30))
CREATE TABLE PROVIDERIDS (ID INT, PARENTID INT, QUALIFIER VARCHAR(20), IDENTIFIER VARCHAR(30))
INSERT INTO TEMPDOCS VALUES (1, 'ROGER, HARPER')
INSERT INTO TEMPDOCS VALUES (2, 'WALTZ, HEALY')

INSERT INTO PROVIDERIDS VALUES (1, 1, 'DEA', 'D12345')
INSERT INTO PROVIDERIDS VALUES (2, 1, 'NPI', 'N12345')
INSERT INTO PROVIDERIDS VALUES (3, 1, 'LIC', 'L12345')
INSERT INTO PROVIDERIDS VALUES (4, 2, 'NPI', 'N23456')
INSERT INTO PROVIDERIDS VALUES (5, 2, 'REG', 'R23456')

DECLARE @cols AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX),
        @id as int = 1;

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(QUALIFIER) 
            FROM PROVIDERIDS
            LEFT OUTER JOIN TEMPDOCS on TEMPDOCS.DOCID = PROVIDERIDS.PARENTID
            WHERE DOCID = @id
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT DOCID, NAME, ' + @cols + ' from 
            (
                select TEMPDOCS.DOCID, TEMPDOCS.NAME, PROVIDERIDS.QUALIFIER, PROVIDERIDS.IDENTIFIER FROM TEMPDOCS
                LEFT OUTER JOIN PROVIDERIDS ON PROVIDERIDS.PARENTID=TEMPDOCS.DOCID
                WHERE TEMPDOCS.DOCID = ' + CAST(@ID AS VARCHAR(30)) + '
           ) x
            pivot 
            (
                MAX(IDENTIFIER)
                FOR QUALIFIER IN (' + @cols + ')
            ) p '


execute(@query)

このコードを、TABLE を返すユーザー定義関数に変換したいと考えています。私はそれをやってみましたが、それを機能させることができませんでした:

CREATE FUNCTION udfGetProviderIds (@DoctorId INT)
RETURNS TABLE
AS
BEGIN
    DECLARE @cols AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX),
        @id as int = 1;

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(QUALIFIER) 
            FROM PROVIDERIDS
            LEFT OUTER JOIN TEMPDOCS on TEMPDOCS.DOCID = PROVIDERIDS.PARENTID
            WHERE DOCID = @id
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT DOCID, NAME, ' + @cols + ' from 
            (
                select TEMPDOCS.DOCID, TEMPDOCS.NAME, PROVIDERIDS.QUALIFIER, PROVIDERIDS.IDENTIFIER FROM TEMPDOCS
                LEFT OUTER JOIN PROVIDERIDS ON PROVIDERIDS.PARENTID=TEMPDOCS.DOCID
                WHERE TEMPDOCS.DOCID = ' + CAST(@ID AS VARCHAR(30)) + '
           ) x
            pivot 
            (
                MAX(IDENTIFIER)
                FOR QUALIFIER IN (' + @cols + ')
            ) p '


    RETURN execute(@query)  
END

次のエラーが表示されます:

Msg 102, Level 15, State 31, Procedure udfGetProviderIds, Line 32
Incorrect syntax near 'BEGIN'.

リターン句でTABLEと構造を宣言せずにこれを機能させる方法はありますか? または、動的ピボットを使用して UDF を作成するより良い方法はありますか?

4

1 に答える 1

0

Aaronが説明したように、UDFで動的SQLを使用することはできませんが、すべての関数定義をストアプロシージャに入れるだけで、ストアドプロシージャから返された結果を次のような一時テーブルに取得する方法を考えることができます

CREATE PROC usp_GetProviderIds 
@DoctorId INT
AS
BEGIN
    DECLARE @cols AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX),
        @id as int = 1;

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(QUALIFIER) 
            FROM PROVIDERIDS
            LEFT OUTER JOIN TEMPDOCS on TEMPDOCS.DOCID = PROVIDERIDS.PARENTID
            WHERE DOCID = @id
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT DOCID, NAME, ' + @cols + ' from 
            (
                select TEMPDOCS.DOCID, TEMPDOCS.NAME, PROVIDERIDS.QUALIFIER, PROVIDERIDS.IDENTIFIER FROM TEMPDOCS
                LEFT OUTER JOIN PROVIDERIDS ON PROVIDERIDS.PARENTID=TEMPDOCS.DOCID
                WHERE TEMPDOCS.DOCID = ' + CAST(@ID AS VARCHAR(30)) + '
           ) x
            pivot 
            (
                MAX(IDENTIFIER)
                FOR QUALIFIER IN (' + @cols + ')
            ) p '


    EXECUTE sp_Executesql @query  
END

そして、次のようにして、返された結果セットを一時テーブルに取得できます。

CREATE TABLE #TempTable (Col1, Col2.....)
INSERT INTO #TempTable
EXEC usp_GetProviderIds @DoctorId
于 2013-11-05T23:25:09.067 に答える