2012-04-19 4 views
0

いくつかのパラメータに基づいて行を出力するtsqlストアドプロシージャを作成しようとしています。究極の目的は、行を別のテーブルに移動することです。そのため、私はカウントを持っています。移動している行の数を把握したいと思います。 2つのテーブル、NotesExtraNotesがあります。 ExtraNotesには、最初のテーブルからオーバーフロー情報が格納されます。IF文を使用した後にDBから正しい行を出力できない

ifステートメントを使用して、NoteTypeというパラメーターに基づいて正しい行を選択していますが、正しい選択ステートメントをifに出力する方法がわかりません。私は、各if内のselect文が

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)) 

Output screenshot

+0

私はここで、ストアドプロシージャよりもより良いサービスを提供でしょうテーブルを返す関数を使用してのように感じます。チェックアウトテーブル値関数:http://msdn.microsoft.com/en-us/library/ms191165aspx – Zugwalt

+0

あなたがここで何をしようとしているのか、あなたがすでに持っているものが何であるのか、私たちに何を求めているのかは不明です。 – RBarryYoung

+0

これをMのパラメータで実行すると、たとえば、Notetype MとSが間違っている行が返されます。 – karmaplus

答えて

0

あなたがやろうとしているものは不明です。データとデータに関するいくつかの統計情報の両方を探しているようですが、実際にどのデータが必要なのか、構造が何であるべきかはわかりません。これらを論理の別々の断片に分割する方が簡単でしょうか?出力するデータをマップし、各項目のコードを別々に作成する方が簡単です。

列とサンプルデータを数行に渡すことができるかどうか、そしてそのデータがコードを通じて実行された場合のサンプル出力を明確にすることができます。

1つの提案 フィルタは何もフィルタリングしないので、フィルタは各クエリに個別にしか適用されないため、2番目のクエリで必要以上に多くのデータが返されます。これが意味をなさない場合は、フィルタリングに使用できるNoteTypeの変数がすでにあります。これにより、データが正しくフィルタリングされ、if-else if文のセット全体が置き換えられるようになりました。これは、変数が正しいデータを直接選択するためです。あなたはちょうどあなたがそれらを生成するために、OVER句を使用することができ、あなたの行でカウントをしたい場合ので、代わりに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 
+0

残念ながら、マニュアルタイプとSタイプのノートタイプは2種類しかありません。 Bは私の頭の中に「両方」を意味しますが、決してその列には入力しないでください。私はいくつかのサンプルデータを今投稿に追加しようとします。 – karmaplus

+0

http://i2.photobucket.com/albums/y19/_karma_/code/oupl.png出力スクリーンショット – karmaplus

0

を使用することができます。 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はヌル)をカウントだけで取得します。

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

関連する問題