使用IF语句后,无法从DB输出正确的行

时间:2012-04-19 18:42:21

标签: sql sql-server-2008 tsql

我正在尝试创建一个tsql存储过程,它将根据一些参数输出行。最终的目标是将行移动到另一个表,这就是为什么我有计数 - 我想跟踪我正在移动的行数。有两个表 - NotesExtraNotesExtraNotes保存第一个表中的溢出信息。

我正在使用if语句根据名为NoteType的参数选择正确的行,但我不知道如何在if中输出正确的select语句。我知道每个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

2 个答案:

答案 0 :(得分:0)

目前还不清楚你要做什么。您似乎正在寻找数据和一些有关数据的统计数据,但我们不知道您实际想要什么数据,或者结构应该是什么。是否更容易将这些分成单独的逻辑?可以更简单地绘制出您想要输出的数据,并单独为每个项目构建代码。

您可以澄清是否可以为列和示例数据添加几行,以及您希望通过代码运行该数据时的示例输出。

一个建议, if / then语句不会过滤任何内容,因此您将在第二个查询中获得比您想要的更多的数据,因为过滤器仅单独应用于每个查询。如果这对您有意义:您已经有一个可用于过滤的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

答案 1 :(得分:0)

如果您只想对行进行计数,可以使用OVER子句生成它们。如果NoteType在表中只能是S或M,那么传递NULL并使用ISNULL(,)应该得到你想要的。下面的代码提取所有注释,所有相关注释,前两列是每个表的源行总数。我知道这是示例代码,所以我不会对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