2

Oracle から SQL Server に移行しており、BULK COLLECT INTO クエリが入力されたテーブル変数からクエリを変換しています。私はカーソルを使用することを考えています(間違いなく他の提案を受け入れます)が、使用しているクエリを処理するOracleコードでTable_var.FIRST .NEXT.LAST. これらをどのように使用しているかのサンプルコードを次に示します。最初/次/最後がテーブルvarのレコードにインデックスを与えているようです。

TYPE Pers_DOB_LastInitial IS RECORD (
  Person_ID Person.Person_ID%TYPE,
  DOB Person.Birthdate%TYPE,
  LastInitial VARCHAR2(1)
);

TYPE Dup_Table IS TABLE OF Pers_DOB_LastInitial INDEX BY BINARY_INTEGER;

Dup_Tab Dup_Table;

これらの型を使用する関数:

FUNCTION Last_In_Group( pStart NUMBER, pDOB Person.Birthdate%TYPE, pLastInitial VARCHAR2 )
     RETURN NUMBER IS
  vResult NUMBER;
BEGIN
  IF pStart = Dup_Tab.LAST THEN
     RETURN pStart;
  END IF;

  vResult := pStart;

  FOR vIndex IN pStart .. Dup_Tab.LAST LOOP
     IF Dup_Tab.EXISTS( vIndex ) THEN
        IF Dup_Tab( vIndex ).DOB = pDOB AND Dup_Tab( vIndex ).LastInitial = pLastInitial THEN
           vResult := vIndex;
        ELSE
           EXIT;
        END IF;
     END IF;
  END LOOP;

  RETURN vResult;
END Last_In_Group;

コーディングを行う必要はありません。正しい方向に向けるだけでよいのです。カーソルを使用することを考えていますが、T-SQL でカーソルから次のレコードをフェッチするだけで、カーソル (または一時テーブル) の行インデックスを参照する同等の方法があるかどうかを知りたいだけです。 )。


EDIT:私はちょうど次のことを発見し、それを調べています。これが追求するのに適した方法なのか、それともカーソルの方が優れているのかについてのヒントは間違いなく開かれています。

http://www.sql-server-performance.com/2004/operations-no-cursors/2/

DECLARE @dupTab TABLE (
    person_id numeric(8,0),
    DOB date,
    LastInitial char(1)
)

INSERT @dupTab
SELECT ...
4

3 に答える 3

0

何を求めているのか 100% よくわかりませんが、Sql Server 2012の新しいLEADLAGFIRST_VALUE、およびLAST_VALUEキーワードを見ましたか?

于 2013-03-04T17:22:56.673 に答える
0

テーブルが Dup_Tab と呼ばれ、@DOB と @LastInitial が関数に渡された変数であると仮定すると、これは機能するでしょうか?

select PersonID from(
select
 rank = row_number() over (order by DOB DESC, LastInitial DESC),
 PersonID
from dup_tab where DOB=@DOB and LastInitial=@LastInitial
) subgroup 
where rank=1

ウィンドウ化された Rank() 関数を使用して、DOB/LastInitial に基づいて各レコードに行番号を割り当て、ランク = 1 の行を選択して、特定の DOB を持つ一連の人物の最後のレコードを取得します。そしてラストイニシャル。

于 2013-03-04T17:56:06.800 に答える
0

サンプル コードを SQL-Server の対応するコードに翻訳しました。行ごとの処理を行う場合、最もパフォーマンスの高い方法は FAST_FORWARD カーソルを使用することです。

コード:

    IF  EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[Last_In_Group]') AND xtype in (N'FN', N'IF', N'TF'))
        drop function  Last_In_Group
    go

    create function Last_In_Group(@pStart  int, @pDOB date, @pLastInitial varchar(1))
    returns int
    AS
    BEGIN
        DECLARE @Dup_Tab TABLE(
            Person_ID int,
            DOB date,
            LastInitial varchar(1)
        )
        -- populate the table with some data
        insert @Dup_Tab values
        (1, '31.12.2013', 'P'), (2, '24.12.2013', 'C'), (3, '24.12.2013', 'C')

        declare @vResult int = 0,
                @cDOB date,
                @cLastInitial varchar(1)

        if(@vResult = @pStart) return @pStart
        set @vResult = @pStart

        -- loop over your data with a fast cursor
        declare cur cursor FAST_FORWARD for select DOB, LastInitial from @Dup_Tab
        open cur
        fetch next from cur
        into @cDOB, @cLastInitial

        while @@FETCH_STATUS = 0
        begin
            if(@cDOB = @pDOB and @cLastInitial = @pLastInitial)
                set @vResult += 1
            fetch next from cur
            into @cDOB, @cLastInitial
        end

        return @vResult;
    end
    go

    print dbo.Last_In_Group(1, '24.12.2013', 'C')
    go

上記のサンプルではうまくいかないかもしれませんが、これがどこに進むべきかのヒントになることを願っています.

于 2013-07-04T12:19:58.840 に答える