0

DBA が関数をプロシージャに変更したため、これに対応するためにプロシージャの一部を修正しています。while ループがある手順の 1 つで、これに関する問題に遭遇しました。

新しいプロシージャ (#DGContol) から一時テーブルを作成し、次の while ループを作成します。

SELECT @MinRcd = MIN(RcdNum) FROM #PortfolioDisclosure 
SELECT @MaxRcd = MAX(RcdNum) FROM #PortfolioDisclosure 

SET @RcdNum = @MinRcd
WHILE @RcdNum <= @MaxRcd

BEGIN

    -- Temporarily assign values to variables
    SELECT
            @PortfolioGroup = PortfolioCode
        ,   @EndDateTime    = MaxPositionDate_DetailedDisclosure

    FROM  #PortfolioDisclosure
    WHERE RcdNum = @RcdNum


    INSERT INTO #PositionsTable
        SELECT


                fi.ID_ISIN                          AS [Fund_ISIN]                  
            ,   RTRIM(a.acct_id)                    AS [Internal_Portfolio_Code]    
            ,   a.acct_desc                         AS [Portfolio/Fund_Name]        
            ,   CONVERT(CHAR(11),p.as_of_tms,103)   AS [Portfolio_Date]         
            ,   a.alt_curr_cde                      AS [Portfolio_Base_Ccy]     
            ,   i.iss_desc                          AS [Security_Description]       
            ,   RTRIM(i.pref_iss_id)                AS [Security_ID SEDOL/Internal]
            ,   RTRIM(ia.iss_id)                    AS [Security_ID ISIN]           
            ,   i.denom_curr_cde                    AS [Denomination_Ccy]           

            ,   SUM(p.valval_alt_cmb_amt) OVER (PARTITION BY RTRIM(a.acct_id))      
                                                    AS [Total_Fund_Value]

            ,   p.orig_quantity                     AS [Shares/Par_Value]           
            ,   p.valval_alt_cmb_amt                AS [Market_Value]               
            ,   p.fld5_rte                          AS [Pct_of_NAV] 

            ,   SUM(CASE WHEN i.issue_cls1_cde = '010' THEN p.valval_alt_cmb_amt ELSE 0 END) OVER (PARTITION BY a.acct_id)      
                                                    AS [Cash/Cash_Equivalents]

            ,   i.inc_proj_cmb_rte                  AS [Coupon_Rate]                
            ,   CONVERT(CHAR(11),i.mat_exp_dte,103) AS [Maturity_Date]              


        FROM dw_position_dg AS p

            INNER JOIN #DGControl AS dgc -- [M]onthly, [M]ost recent position
                ON dgc.DataGrpCtlNum = p.data_grp_ctl_num

            INNER JOIN dw_ivw_acct AS a WITH (NOLOCK)
                ON a.acct_id = p.acct_id

            INNER JOIN dw_issue_dg AS i WITH (NOLOCK)
                ON i.instr_id = p.instr_id

            LEFT OUTER JOIN dw_issue_alt_id AS ia WITH (NOLOCK)
                ON ia.instr_id = i.instr_id
                AND ia.id_ctxt_typ = 'ISIN'

            INNER JOIN #PortfolioDisclosure AS fi
                ON fi.PortfolioCode = p.acct_id
                and fi.MaxPositionDate_DetailedDisclosure >= p.as_of_tms

        WHERE RTRIM(a.acct_id) NOT IN ( SELECT xref.internal_value FROM  dbo.DP_CrossReference as xref
                                        WHERE xref.Codeset_type_id = 10401 
                                        AND xref.Originator_id = 'DataVendorPortfolioExclusion')

            -- Clear down variable values
            SET @PortfolioGroup = NULL
            --SET @StartDateTime = NULL
            SET @EndDateTime = NULL

            -- Move to next record
            SET @RcdNum = @RcdNum + 1

END -- END WHILE LOOP

ただし、これは多くの重複レコードを返します。一時テーブル #DGControl を元の関数に置き換えると、正しい数のレコードが得られます。

問題が何であるか、テーブル #DGControl を使用して正しいレコード数を取得できるように、この while ループをどのように再コーディングできるかはよくわかりません。誰でも助けることができますか?

4

3 に答える 3

0

SELECT * FROM OldFunction(args ..)の出力をEXEC NewStoredProcedure args ...と比較しましたか?もしそうなら、返されたデータは同じように見えますか、それともDBAが関数をprocにリファクタリングしたときに重複が忍び込んでいますか?

その場合は、最初にspからの出力を重複排除してから、残りのコードで実行する必要があります。つまり、両方に同じ引数を使用しているが、結果が異なる場合は、DBAに戻る必要があります。

于 2012-09-28T13:19:57.200 に答える
0

このコードでは、ローカル変数 (@PortfolioGroup、@EndDateTime) のいずれも使用していません。同じレコードセットを N 回挿入するだけです。また、これを一時テーブルや while ループを使用せずに単一の選択クエリとして記述できると、混乱が少なくなると思います。

于 2012-09-28T16:25:48.647 に答える
0

ご意見ありがとうございます。私は問題を解決しました。私のコードは次のようになります。

BEGIN

SELECT @MinRcd = MIN(RcdNum) FROM #PortfolioDisclosure 
SELECT @MaxRcd = MAX(RcdNum) FROM #PortfolioDisclosure 

SET @RcdNum = @MinRcd
WHILE @RcdNum <= @MaxRcd

BEGIN

    -- Temporarily assign values to variables
    SELECT
            @PortfolioGroup = PortfolioCode
        ,   @EndDateTime    = MaxPositionDate_DetailedDisclosure

    FROM  #PortfolioDisclosure
    WHERE RcdNum = @RcdNum

    -- Insert DGControl record into table based on the MaxPositionDate_DetailedDisclosure from Portfolio Disclosure function
    INSERT INTO #DGControl
        EXEC InfoPortal..usp_Generic_DGControl '', '', @PortfolioGroup, '1', @EndDateTime, @EndDateTime, @PeriodType, 'M', 'POSITION'    -- [M]onthly, [M]ost recent position

    -- Insert into #PositionsTable
    INSERT INTO #PositionsTable
        SELECT
                fi.ID_ISIN                          AS [Fund_ISIN]                  
            ,   RTRIM(a.acct_id)                    AS [Internal_Portfolio_Code]    
            ,   a.acct_desc                         AS [Portfolio/Fund_Name]        
            ,   CONVERT(CHAR(11),p.as_of_tms,103)   AS [Portfolio_Date]         
            ,   a.alt_curr_cde                      AS [Portfolio_Base_Ccy]     
            ,   i.iss_desc                          AS [Security_Description]       
            ,   RTRIM(i.pref_iss_id)                AS [Security_ID SEDOL/Internal]
            ,   RTRIM(ia.iss_id)                    AS [Security_ID ISIN]           
            ,   i.denom_curr_cde                    AS [Denomination_Ccy]           

            ,   SUM(p.valval_alt_cmb_amt) OVER (PARTITION BY RTRIM(a.acct_id))      
                                                    AS [Total_Fund_Value]

            ,   p.orig_quantity                     AS [Shares/Par_Value]           
            ,   p.valval_alt_cmb_amt                AS [Market_Value]               
            ,   p.fld5_rte                          AS [Pct_of_NAV] 

            ,   SUM(CASE WHEN i.issue_cls1_cde = '010' THEN p.valval_alt_cmb_amt ELSE 0 END) OVER (PARTITION BY a.acct_id)      
                                                    AS [Cash/Cash_Equivalents]

            ,   i.inc_proj_cmb_rte                  AS [Coupon_Rate]                
            ,   CONVERT(CHAR(11),i.mat_exp_dte,103) AS [Maturity_Date]              

        FROM dw_position_dg AS p

            INNER JOIN #DGControl AS dgc
                ON dgc.DataGrpCtlNum = p.data_grp_ctl_num

            INNER JOIN dw_ivw_acct AS a WITH (NOLOCK)
                ON a.acct_id = p.acct_id

            INNER JOIN dw_issue_dg AS i WITH (NOLOCK)
                ON i.instr_id = p.instr_id

            LEFT OUTER JOIN dw_issue_alt_id AS ia WITH (NOLOCK)
                ON ia.instr_id = i.instr_id
                AND ia.id_ctxt_typ = 'ISIN'

            INNER JOIN #PortfolioDisclosure AS fi
                ON fi.PortfolioCode = p.acct_id

            -- Clear down variable values
            SET @PortfolioGroup = NULL
            --SET @StartDateTime = NULL
            SET @EndDateTime = NULL
            -- Clear down #DGControl table to allow new record to be inserted
            DELETE FROM #DGControl
            -- Move to next record
            SET @RcdNum = @RcdNum + 1

END -- END WHILE LOOP

最初にストアド プロシージャ usp_Generic_DGControl の実行を追加し、各ループの後にそれをクリアすると、レコードの複製が停止しました。

于 2012-10-01T13:16:59.410 に答える