0

いくつかのパラメーターに基づいて行を出力する tsql ストアド プロシージャを作成しようとしています。最終的な目的は、行を別のテーブルに移動することです。そのため、カウントがあります。移動している行の数を追跡したいと考えています。と の 2 つのテーブルがありNotesますExtraNotes。はExtraNotes、最初のテーブルからのオーバーフロー情報を保持します。

ステートメントを使用して、if呼び出されたパラメーターに基づいて正しい行を選択していますNoteTypeが、 内で正しい選択ステートメントを出力する方法がわかりませんififそれぞれの選択ステートメントが間違っていることを知っています

select * 
from dbo.Notes 
left join dbo.ExtraNotes on Notes.NoteID = dbo.ExtraNotes.NoteID 
where NoteDate <= @Date

正しい行を出力し、これをより適切に再構築する方法について、誰かがいくつかの指針を提供できますか?

完全なコードはこちらです。

alter proc selectrows 
   --external variables
   @Date datetime,
   @NoteType varchar(2)
as
--internal variables
--Count variables, before any changes
declare @count_rowsBefore int
declare @count_Extra_rowsBefore int

--Count variables of selected rows to be moved

declare @count_SelectedRows int
declare @count_Extra_SelectedRows int

select @count_rowsBefore = count(*)
from dbo.Notes

select @count_Extra_SelectedRows = count(*)
from dbo.ExtraNotes


if(@NoteType= 'B')
begin
select @count_SelectedRows = count(dbo.Notes.NoteID), @count_Extra_SelectedRows =            count(dbo.ExtraNotes.NoteID)
        from dbo.Notes
        left join dbo.ExtraNotes on
        Notes.NoteID = dbo.ExtraNotes.NoteID
        where NoteDate <= @Date

        select *
        from dbo.Notes
        left join dbo.ExtraNotes on
        Notes.NoteID = dbo.ExtraNotes.NoteID
        where NoteDate <= @Date
end
else if(@NoteType = 'S')
  begin
  select @count_SelectedRows = count(dbo.Notes.NoteID), 
@count_Extra_SelectedRows = count(dbo.ExtraNotes.NoteID)
        from dbo.Notes
        left join dbo.ExtraNotes on
        Notes.NoteID = dbo.ExtraNotes.NoteID
        where NoteDate <= @Date
        and NoteType = 'S'

        select *
        from dbo.Notes
        left join dbo.ExtraNotes on
        Notes.NoteID = dbo.ExtraNotes.NoteID
        where NoteDate <= @Date
end
else if (@NoteType = 'M')
begin
select @count_SelectedRows = count(dbo.Notes.NoteID),
@count_Extra_SelectedRows =  count(dbo.ExtraNotes.NoteID)
        from dbo.Notes
        left join dbo.ExtraNotes on
        Notes.NoteID = dbo.ExtraNotes.NoteID
        where NoteDate <= @Date
        and NoteType = 'M'

        select *
        from dbo.Notes
        left join dbo.ExtraNotes on
        Notes.NoteID = dbo.ExtraNotes.NoteID
        where NoteDate <= @Date
  end
 else
  begin
  raiserror('Please enter a valid Note Read Type= M, S or B',16,1)
  end

Print 'Total Number of rows: ' + cast(@count_rowsBefore as varchar(10))
Print 'Total Number of "Extra" rows: ' + cast(@count_Extra_RowsBefore as varchar(10))

Print '-----------------------------------------------'
Print 'Total Number of rows to Move: ' + cast(@count_SelectedRows as varchar(10))
Print 'Total Number of "Extra" Rows to Move: ' + cast(@count_Extra_SelectedRows 
as varchar(10))

出力スクリーンショット

4

2 に答える 2

0

行のカウントだけが必要な場合は、OVER 句を使用してそれらを生成できます。NoteType がテーブル内で S または M しかない場合は、NULL を渡して ISNULL(, ) を使用すると、必要なものが得られます。以下のコードは、すべてのメモ、関連するすべてのメモを取得します。最初の 2 列は、各テーブルのソース行の総数です。これはサンプル コードであることはわかっているので、select * についてあまり神経質になることはありません。

下部のリンクは OVER 句を超えています。

CREATE PROCEDURE selectRows
    ( @Date DATETIME
      , @NoteType VARCHAR(2) -- Pass NULL for both
    )
AS
    select count(dbo.notes.noteid) 
               over() as notecount
           , count(dbo.ExtraNotes.NoteID)
               over() as extraNoteCount
           , *
    from dbo.Notes 
    left join dbo.ExtraNotes
        on Notes.NoteID = dbo.ExtraNotes.NoteID
    where NoteDate <= @Date
      and NoteType = ISNULL(@NoteType, NoteType);

これらのカウントのすべてのコピーが必ずしも必要なわけではないため、ヘッダー行で結合することは、あなたが考えていたことよりも多いかもしれません。以下のコードは、カウントのみですべてのメモとヘッダー行 (noteid が null) を取得します。

CREATE PROCEDURE selectRows
    ( @Date DATETIME
      , @NoteType VARCHAR(2) -- Pass NULL for both
    )
AS
    select *
       , CAST(NULL AS INT) noteCount
       , CAST(NULL AS INT) extraNoteCount
    from dbo.Notes 
    left join dbo.ExtraNotes
        on Notes.NoteID = dbo.ExtraNotes.NoteID
    where NoteDate <= @Date
      and NoteType = ISNULL(@NoteType, NoteType)
    UNION ALL
    SELECT NULL
       , NULL -- Repeat for as many columns as are in the select * above
       , count(dbo.Notes.NoteID)
       , count(dbo.ExtraNotes.NoteID)
    from dbo.Notes 
    left join dbo.ExtraNotes
        on Notes.NoteID = dbo.ExtraNotes.NoteID
    where NoteDate <= @Date
      and NoteType = ISNULL(@NoteType, NoteType)

;

http://msdn.microsoft.com/en-us/library/ms189461.aspx

于 2012-04-19T22:20:19.520 に答える
0

あなたが何をしようとしているのかは不明です。データとデータに関するいくつかの統計の両方を探しているようですが、実際に必要なデータや、構造がどうあるべきかはわかりません。これらを別々のロジックに分割する方が簡単でしょうか? 出力したいデータをマッピングし、各項目のコードを個別に作成する方が簡単な場合があります。

列とサンプル データを含む 2 行を指定できるかどうか、およびそのデータがコードで実行された場合に必要なサンプル出力を明確にすることができます。

1 つの提案は、If/then ステートメントは何もフィルタリングしないため、フィルターは各クエリに個別にのみ適用されるため、2 番目のクエリでは必要以上のデータが返されます。これが理にかなっている場合: フィルタリングに使用できる NoteType を持つ変数が既にあります。これにより、データが正しくフィルター処理され、コードが変数を使用して正しいデータを直接選択するようになったため、if-else if ステートメントのセット全体を置き換える必要があります。したがって、if ステートメントを使用する代わりに、次を使用できます。

select @count_SelectedRows = count(dbo.Notes.NoteID), 
        @count_Extra_SelectedRows =  count(dbo.ExtraNotes.NoteID)
  from dbo.Notes left join dbo.ExtraNotes 
    on Notes.NoteID = dbo.ExtraNotes.NoteID
  where NoteDate <= @Date
  and NoteType = @NoteType

select * 
  from dbo.Notes left join dbo.ExtraNotes 
    on Notes.NoteID = dbo.ExtraNotes.NoteID         
  where NoteDate <= @Date and NoteType = @NoteType
于 2012-04-19T19:03:54.083 に答える